Skip to content

Commit

Permalink
[Fix] TTS (#139)
Browse files Browse the repository at this point in the history
* Revert "[Fix] TTS (#137)"

This reverts commit c5bd6b7.

* Revert "[Fix] Исправление ТТСа (#136)"

This reverts commit 3759acb.

* Revert "[Port] TTS (#121)"

This reverts commit 0db8f3a.

* new TTS

* new TTS

* new TTS

* new TTS

* fix
  • Loading branch information
Spatison authored Dec 6, 2024
1 parent c5bd6b7 commit 3b0dadc
Show file tree
Hide file tree
Showing 35 changed files with 1,385 additions and 647 deletions.
3 changes: 0 additions & 3 deletions Content.Client/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Content.Client._White.TTS;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
Expand Down Expand Up @@ -73,7 +72,6 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly JoinQueueManager _joinQueue = default!;
[Dependency] private readonly DiscordAuthManager _discordAuth = default!;
[Dependency] private readonly TTSManager _ttsManager = default!; // WD EDIT

public override void Init()
{
Expand Down Expand Up @@ -168,7 +166,6 @@ public override void PostInit()
_documentParsingManager.Initialize();
_joinQueue.Initialize();
_discordAuth.Initialize();
_ttsManager.Initialize(); // WD EDIT

_baseClient.RunLevelChanged += (_, args) =>
{
Expand Down
2 changes: 0 additions & 2 deletions Content.Client/IoC/ClientContentIoC.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Content.Client._White.TTS;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
Expand Down Expand Up @@ -53,7 +52,6 @@ public static void Register()
collection.Register<ISharedPlaytimeManager, JobRequirementsManager>();
IoCManager.Register<JoinQueueManager>();
IoCManager.Register<DiscordAuthManager>();
IoCManager.Register<TTSManager>(); // WD EDIT
}
}
}
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ private void UpdateChanges()
var isTtsVolumeSame =
Math.Abs(TtsVolumeSlider.Value - _cfg.GetCVar(WhiteCVars.TTSVolume) * 100f / ContentAudioSystem.TTSMultiplier) < 0.01f; // WD EDIT


var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources);
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
var isRestartSoundsSame = RestartSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.RestartSoundsEnabled);
Expand Down
194 changes: 194 additions & 0 deletions Content.Client/_White/TTS/AnnounceTTSSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared._White.TTS;
using Content.Shared.CCVar;
using Content.Shared.GameTicking;
using Robust.Client.ResourceManagement;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.Player;
using Robust.Shared.Utility;

namespace Content.Client._White.TTS;

// ReSharper disable once InconsistentNaming
public sealed class AnnounceTTSSystem : EntitySystem
{
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;

private ISawmill _sawmill = default!;
private readonly MemoryContentRoot _contentRoot = new();
private ResPath _prefix;

private float _volume = 0.0f;
private ulong _fileIdx = 0;
private static ulong _shareIdx = 0;

private TTSAudioStream? _currentlyPlaying;
private readonly Queue<TTSAudioStream> _queuedStreams = new();

/// <inheritdoc />
public override void Initialize()
{
_prefix = ResPath.Root / $"TTSAnon{_shareIdx++}";
_resourceCache.AddRoot(_prefix, _contentRoot);
_sawmill = Logger.GetSawmill("AnnounceTTSSystem");
_cfg.OnValueChanged(CCVars.AnnouncerVolume, OnTtsVolumeChanged, true);
SubscribeNetworkEvent<AnnounceTTSEvent>(OnAnnounceTTSPlay);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(OnCleanup);
}

private void OnCleanup(RoundRestartCleanupEvent ev)
{
EndStreams();
_contentRoot.Clear();
}

/// <inheritdoc />
public override void FrameUpdate(float frameTime)
{
if (_queuedStreams.Count == 0)
return;

var isDoNext = true;
try
{
isDoNext = _currentlyPlaying == null ||
(_currentlyPlaying.AudioStream != null && TerminatingOrDeleted(_currentlyPlaying.AudioStream!.Value))
|| !(_currentlyPlaying.AudioStream?.Comp.Playing ?? false);
}
catch (Exception err)
{
isDoNext = true;
}

if (isDoNext)
{
_currentlyPlaying?.StopAndClean(this);
ProcessEntityQueue();
}

}

/// <inheritdoc />
public override void Shutdown()
{
_cfg.UnsubValueChanged(CCVars.AnnouncerVolume, OnTtsVolumeChanged);
EndStreams();
_contentRoot.Dispose();
}

private void OnAnnounceTTSPlay(AnnounceTTSEvent ev)
{
var volume = Math.Max(-5f, SharedAudioSystem.GainToVolume(_volume));


var file = new ResPath(ev.AnnouncementSound);

if (!_resourceCache.TryGetResource<AudioResource>(file, out var audio))
{
_sawmill.Error($"Server tried to play audio file {ev.AnnouncementSound} which does not exist.");
return;
}

if (TryCreateAudioSource(file, ev.AnnouncementParams.Volume, out var sourceAnnounce))
AddEntityStreamToQueue(sourceAnnounce);
if (ev.Data.Length > 0 && TryCreateAudioSource(ev.Data, volume, out var source))
{
source.DelayMs = (int) audio.AudioStream.Length.TotalMilliseconds;
AddEntityStreamToQueue(source);
}

}

private void AddEntityStreamToQueue(TTSAudioStream stream)
{
_queuedStreams.Enqueue(stream);
}

private void ProcessEntityQueue()
{
if (_queuedStreams.TryDequeue(out _currentlyPlaying))
PlayEntity(_currentlyPlaying);
}

private bool TryCreateAudioSource(byte[] data, float volume, [NotNullWhen(true)] out TTSAudioStream? source)
{
var filePath = new ResPath($"{_fileIdx++}.ogg");
_contentRoot.AddOrUpdateFile(filePath, data);

var audioParams = AudioParams.Default.WithVolume(volume).WithRolloffFactor(1f).WithMaxDistance(float.MaxValue).WithReferenceDistance(1f);
var soundPath = new SoundPathSpecifier(_prefix / filePath, audioParams);

source = new TTSAudioStream(soundPath, filePath);

return true;
}

private bool TryCreateAudioSource(ResPath audio, float volume,
[NotNullWhen(true)] out TTSAudioStream? source)
{
var audioParams = AudioParams.Default.WithVolume(volume).WithRolloffFactor(1f).WithMaxDistance(float.MaxValue).WithReferenceDistance(1f);

var soundPath = new SoundPathSpecifier(audio, audioParams);


source = new TTSAudioStream(soundPath, null);

return true;
}

private void PlayEntity(TTSAudioStream stream)
{
stream.AudioStream = _audio.PlayGlobal(stream.Source, Filter.Local(), false);
}

private void OnTtsVolumeChanged(float volume)
{
_volume = volume;
}

private void EndStreams()
{
foreach (var stream in _queuedStreams)
{
stream.StopAndClean(this);
}

_queuedStreams.Clear();
}

// ReSharper disable once InconsistentNaming
private sealed class TTSAudioStream
{
public SoundPathSpecifier Source { get; }
public ResPath? CacheFile { get; }
public Entity<AudioComponent>? AudioStream { get; set; }

public int DelayMs { get; set; }

public TTSAudioStream(SoundPathSpecifier source, ResPath? cacheFile, int delayMs = 0)
{
Source = source;
CacheFile = cacheFile;
DelayMs = delayMs;
}

public void StopAndClean(AnnounceTTSSystem sys)
{
if (AudioStream != null)
{
sys._audio.Stop(AudioStream.Value,AudioStream.Value);

}
if (CacheFile != null)
{
sys._contentRoot.RemoveFile(CacheFile.Value);
}
}
}
}
38 changes: 14 additions & 24 deletions Content.Client/_White/TTS/HumanoidProfileEditor.TTS.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,31 @@
using System.Linq;
using Content.Client._White.TTS;
using Content.Shared.Preferences;
using Content.Shared._White.TTS;
using Robust.Shared.Random;
using Content.Shared.Preferences;

// ReSharper disable InconsistentNaming
// ReSharper disable once CheckNamespace
namespace Content.Client.Lobby.UI;

public sealed partial class HumanoidProfileEditor
{
private TTSSystem _ttsSystem = default!;
private TTSManager _ttsManager = default!;
private IRobustRandom _random = default!;

private List<TTSVoicePrototype> _voiceList = default!;

private readonly string[] _sampleText =
[
"Помогите, клоун насилует в технических тоннелях!",
"ХоС, ваши сотрудники украли у меня собаку и засунули ее в стиральную машину!",
"Агент синдиката украл пиво из бара и взорвался!",
"Врача! Позовите врача!"
];
private List<TTSVoicePrototype> _voiceList = new();

private void InitializeVoice()
{
_random = IoCManager.Resolve<IRobustRandom>();
_ttsManager = IoCManager.Resolve<TTSManager>();
_ttsSystem = IoCManager.Resolve<IEntityManager>().System<TTSSystem>();
_voiceList = _prototypeManager.EnumeratePrototypes<TTSVoicePrototype>().Where(o => o.RoundStart).ToList();
_voiceList = _prototypeManager
.EnumeratePrototypes<TTSVoicePrototype>()
.Where(o => o.RoundStart)
.OrderBy(o => Loc.GetString(o.Name))
.ToList();

VoiceButton.OnItemSelected += args =>
{
VoiceButton.SelectId(args.Id);
SetVoice(_voiceList[args.Id].ID);
};

VoicePlayButton.OnPressed += _ => { PlayTTS(); };
VoicePlayButton.OnPressed += _ => PlayPreviewTTS();
}

private void UpdateTTSVoicesControls()
Expand All @@ -62,16 +50,18 @@ private void UpdateTTSVoicesControls()
}

var voiceChoiceId = _voiceList.FindIndex(x => x.ID == Profile.Voice);
if (!VoiceButton.TrySelectId(voiceChoiceId) && VoiceButton.TrySelectId(firstVoiceChoiceId))
if (!VoiceButton.TrySelectId(voiceChoiceId) &&
VoiceButton.TrySelectId(firstVoiceChoiceId))
{
SetVoice(_voiceList[firstVoiceChoiceId].ID);
}
}

private void PlayTTS()
private void PlayPreviewTTS()
{
if (Profile is null)
return;

_ttsSystem.StopCurrentTTS(PreviewDummy);
_ttsManager.RequestTTS(PreviewDummy, _random.Pick(_sampleText), Profile.Voice);
_entManager.System<TTSSystem>().RequestGlobalTTS(VoiceRequestType.Preview,Profile.Voice);
}
}
24 changes: 0 additions & 24 deletions Content.Client/_White/TTS/TTSManager.cs

This file was deleted.

Loading

0 comments on commit 3b0dadc

Please sign in to comment.