Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TTS Optimization #2519

Merged
merged 2 commits into from
Feb 1, 2025
Merged
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
3 changes: 3 additions & 0 deletions Content.Client/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
using Robust.Shared.Replays;
using Content.Client.SS220.Discord;
using Robust.Shared.Timing;
using Content.Client.SS220.TTS;

namespace Content.Client.Entry
{
Expand Down Expand Up @@ -81,6 +82,7 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly DiscordPlayerInfoManager _discordPlayerInfoManager = default!; // SS220 discord info manager
[Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!;
[Dependency] private readonly TitleWindowManager _titleWindowManager = default!;
[Dependency] private readonly TTSManager _ttsManager = default!; // SS220 TTS

public override void Init()
{
Expand Down Expand Up @@ -182,6 +184,7 @@ public override void PostInit()
_documentParsingManager.Initialize();
_discordPlayerInfoManager.Initialize(); // SS220 tier info
_titleWindowManager.Initialize();
_ttsManager.Initialize(); // SS220 TTS

_baseClient.RunLevelChanged += (_, args) =>
{
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/IoC/ClientContentIoC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using Content.Shared.Chat;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Players.RateLimiting;
using Content.Client.SS220.TTS;

namespace Content.Client.IoC
{
Expand Down Expand Up @@ -67,6 +68,7 @@ public static void Register()
collection.Register<PlayerRateLimitManager>();
collection.Register<SharedPlayerRateLimitManager, PlayerRateLimitManager>();
collection.Register<TitleWindowManager>();
collection.Register<TTSManager>(); // SS220 TTS
}
}
}
20 changes: 20 additions & 0 deletions Content.Client/SS220/TTS/TTSManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Shared.SS220.TTS;
using Robust.Shared.Network;

namespace Content.Client.SS220.TTS;

public sealed class TTSManager
{
[Dependency] private readonly IClientNetManager _netManager = default!;

public event Action<MsgPlayTts>? PlayTtsReceived;
public event Action<MsgPlayAnnounceTts>? PlayAnnounceTtsReceived;

public void Initialize()
{
_netManager.RegisterNetMessage<MsgPlayTts>(x => PlayTtsReceived?.Invoke(x));
_netManager.RegisterNetMessage<MsgPlayAnnounceTts>(x => PlayAnnounceTtsReceived?.Invoke(x));
}
}
13 changes: 7 additions & 6 deletions Content.Client/SS220/TTS/TTSSystem.Announce.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using Content.Shared.Corvax.CCCVars;
using Content.Shared.SS220.AnnounceTTS;
using Content.Shared.SS220.TTS;
using Robust.Shared.Audio;
using Robust.Shared.Utility;

Expand All @@ -16,30 +16,31 @@ public sealed partial class TTSSystem : EntitySystem
private void InitializeAnnounces()
{
_cfg.OnValueChanged(CCCVars.TTSAnnounceVolume, OnTtsAnnounceVolumeChanged, true);
SubscribeNetworkEvent<AnnounceTTSEvent>(OnAnnounceTTSPlay);
_ttsManager.PlayAnnounceTtsReceived += OnAnnounceTtsPlay;
}

private void ShutdownAnnounces()
{
_cfg.UnsubValueChanged(CCCVars.TTSAnnounceVolume, OnTtsAnnounceVolumeChanged);
_ttsManager.PlayAnnounceTtsReceived -= OnAnnounceTtsPlay;
}

private void OnAnnounceTTSPlay(AnnounceTTSEvent ev)
private void OnAnnounceTtsPlay(MsgPlayAnnounceTts msg)
{
// Early creation of entities can lead to crashes, so we postpone it as much as possible
if (AnnouncementUid == EntityUid.Invalid)
AnnouncementUid = Spawn(null);

var volume = AdjustVolume(isRadio: false, isAnounce: true, isWhisper: false);
var volume = AdjustVolume(TtsKind.Announce);

var audioParams = AudioParams.Default.WithVolume(volume);

// Play announcement sound
var announcementSoundPath = new ResPath(ev.AnnouncementSound);
var announcementSoundPath = new ResPath(msg.AnnouncementSound);
PlaySoundQueued(AnnouncementUid, announcementSoundPath, audioParams, true);

// Play announcement itself
PlayTTSBytes(ev.Data, AnnouncementUid, audioParams, true);
PlayTtsBytes(msg.Data, AnnouncementUid, audioParams, true);
}

private void OnTtsAnnounceVolumeChanged(float volume)
Expand Down
34 changes: 20 additions & 14 deletions Content.Client/SS220/TTS/TTSSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using Content.Shared.Corvax.CCCVars;
using Content.Shared.SS220.TTS;
using Content.Shared.SS220.TTS.Commands;
using Robust.Client.Audio;
using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Components;
Expand All @@ -26,6 +24,7 @@ public sealed partial class TTSSystem : EntitySystem
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IDependencyCollection _dependencyCollection = default!;
[Dependency] private readonly TTSManager _ttsManager = default!;

private ISawmill _sawmill = default!;

Expand Down Expand Up @@ -62,9 +61,10 @@ public override void Initialize()
_cfg.OnValueChanged(CCCVars.TTSVolume, OnTtsVolumeChanged, true);
_cfg.OnValueChanged(CCCVars.TTSRadioVolume, OnTtsRadioVolumeChanged, true);

SubscribeNetworkEvent<PlayTTSEvent>(OnPlayTTS);
SubscribeNetworkEvent<TtsQueueResetMessage>(OnQueueResetRequest);

_ttsManager.PlayTtsReceived += OnPlayTts;

InitializeAnnounces();
}

Expand All @@ -77,6 +77,8 @@ public override void Shutdown()
// clear virtual files
ContentRoot.Clear();

_ttsManager.PlayTtsReceived -= OnPlayTts;

ShutdownAnnounces();
ResetQueuesAndEndStreams();
}
Expand Down Expand Up @@ -157,7 +159,7 @@ public override void FrameUpdate(float frameTime)
SoundPathSpecifier soundPath;
if (request is PlayRequestById requestById)
{
tempFilePath = new ResPath($"{requestById.FileIdx}.wav");
tempFilePath = new ResPath($"{requestById.FileIdx}.ogg");
soundPath = new SoundPathSpecifier(Prefix / tempFilePath.Value, requestById.Params);
}
else if (request is PlayRequestByPath requestByPath)
Expand Down Expand Up @@ -229,16 +231,16 @@ private void PlaySoundQueued(EntityUid entity, ResPath sound, AudioParams? audio
TryQueueRequest(entity, request);
}

private void PlayTTSBytes(byte[] data, EntityUid? sourceUid = null, AudioParams? audioParams = null, bool globally = false)
private void PlayTtsBytes(TtsAudioData data, EntityUid? sourceUid = null, AudioParams? audioParams = null, bool globally = false)
{
_sawmill.Debug($"Play TTS audio {data.Length} bytes from {sourceUid} entity");
if (data.Length == 0)
return;

var finalParams = audioParams ?? AudioParams.Default;

var filePath = new ResPath($"{_fileIdx}.wav");
ContentRoot.AddOrUpdateFile(filePath, data);
var filePath = new ResPath($"{_fileIdx}.ogg");
ContentRoot.AddOrUpdateFile(filePath, data.Buffer);

// Cache does a funny.
// If we have disconnected and reconnected, the Idx will be reset
Expand Down Expand Up @@ -266,22 +268,26 @@ private void PlayTTSBytes(byte[] data, EntityUid? sourceUid = null, AudioParams?
_fileIdx++;
}

private void OnPlayTTS(PlayTTSEvent ev)
private void OnPlayTts(MsgPlayTts msg)
{
var volume = AdjustVolume(ev.IsRadio, isAnounce: false, ev.IsWhisper);

var volume = AdjustVolume(msg.Kind);
var audioParams = AudioParams.Default.WithVolume(volume);

PlayTTSBytes(ev.Data, GetEntity(ev.SourceUid), audioParams);
PlayTtsBytes(msg.Data, GetEntity(msg.SourceUid), audioParams);
}

private float AdjustVolume(bool isRadio, bool isAnounce, bool isWhisper)
private float AdjustVolume(TtsKind kind)
{
var volume = isRadio ? _radioVolume : isAnounce ? VolumeAnnounce : _volume;
var volume = kind switch
{
TtsKind.Radio => _radioVolume,
TtsKind.Announce => VolumeAnnounce,
_ => _volume,
};

volume = SharedAudioSystem.GainToVolume(volume);

if (isWhisper)
if (kind == TtsKind.Whisper)
{
volume -= SharedAudioSystem.GainToVolume(WhisperFade);
}
Expand Down
Loading
Loading