Skip to content

Commit

Permalink
TTS Optimization (#2519)
Browse files Browse the repository at this point in the history
* TTS Optimization

* Fix announce TTS
  • Loading branch information
stalengd authored Feb 1, 2025
1 parent 73e9340 commit b775db5
Show file tree
Hide file tree
Showing 15 changed files with 599 additions and 205 deletions.
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

0 comments on commit b775db5

Please sign in to comment.