Skip to content

Commit

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

* TTS fix

* TTS fix

* RedFoxIV revie
  • Loading branch information
Spatison authored Dec 5, 2024
1 parent 8267e36 commit c5bd6b7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 49 deletions.
32 changes: 19 additions & 13 deletions Content.Server/_White/TTS/TTSManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void Initialize()
/// <param name="speaker">Identifier of speaker</param>
/// <param name="text">SSML formatted text</param>
/// <returns>OGG audio bytes</returns>
public async Task<byte[]?> ConvertTextToSpeech(string speaker, string text, string pitch, string rate, string? effect = null)
public async Task<byte[]?> ConvertTextToSpeech(string speaker, string text)
{
var url = _cfg.GetCVar(WhiteCVars.TTSApiUrl);
if (string.IsNullOrWhiteSpace(url))
Expand Down Expand Up @@ -80,10 +80,7 @@ public void Initialize()
{
ApiToken = token,
Text = text,
Speaker = speaker,
Pitch = pitch,
Rate = rate,
Effect = effect
Speaker = speaker
};

var reqTime = DateTime.UtcNow;
Expand Down Expand Up @@ -143,19 +140,28 @@ private record GenerateVoiceRequest
public string ApiToken { get; set; } = "";

[JsonPropertyName("text")]
public string Text { get; set; } = default!;
public string Text { get; set; } = "";

[JsonPropertyName("speaker")]
public string Speaker { get; set; } = default!;
public string Speaker { get; set; } = "";

[JsonPropertyName("pitch")]
public string Pitch { get; set; } = default!;
[JsonPropertyName("ssml")]
public bool SSML { get; private set; } = true;

[JsonPropertyName("rate")]
public string Rate { get; set; } = default!;
[JsonPropertyName("word_ts")]
public bool WordTS { get; private set; } = false;

[JsonPropertyName("effect")]
public string? Effect { get; set; }
[JsonPropertyName("put_accent")]
public bool PutAccent { get; private set; } = true;

[JsonPropertyName("put_yo")]
public bool PutYo { get; private set; } = false;

[JsonPropertyName("sample_rate")]
public int SampleRate { get; private set; } = 24000;

[JsonPropertyName("format")]
public string Format { get; private set; } = "ogg";
}

private struct GenerateVoiceResponse
Expand Down
29 changes: 4 additions & 25 deletions Content.Server/_White/TTS/TTSSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private async void OnAnnounceRequest(TtsAnnouncementEvent ev)
if (!_prototypeManager.TryIndex(ev.VoiceId, out var ttsPrototype))
return;
var message = FormattedMessage.RemoveMarkup(ev.Message);
var soundData = await GenerateTTS(null, message, ttsPrototype.Speaker, speechRate: "slow", effect: "announce");
var soundData = await GenerateTTS(null, message, ttsPrototype.Speaker, speechRate: "slow");
if (soundData == null)
return;
Filter filter;
Expand Down Expand Up @@ -184,35 +184,14 @@ private async void OnRequestTTS(MsgRequestTTS ev)
RaiseNetworkEvent(new PlayTTSEvent(ev.Uid, soundData, false), Filter.SinglePlayer(session), false);
}

private async Task<byte[]?> GenerateTTS(EntityUid? uid, string text, string speaker, string? speechPitch = null,
string? speechRate = null, string? effect = null)
private async Task<byte[]?> GenerateTTS(EntityUid? uid, string text, string speaker, string? speechRate = null, string? speechPitch = null)
{
var textSanitized = Sanitize(text);
if (textSanitized == "")
return null;

string pitch;
string rate;
if (speechPitch == null || speechRate == null)
{
if (uid == null || !_ttsPitchRateSystem.TryGetPitchRate(uid.Value, out var pitchRate))
{
pitch = "medium";
rate = "medium";
}
else
{
pitch = pitchRate.Pitch;
rate = pitchRate.Rate;
}
}
else
{
pitch = speechPitch;
rate = speechRate;
}

return await _ttsManager.ConvertTextToSpeech(speaker, textSanitized, pitch, rate, effect);
textSanitized = _ttsPitchRateSystem.GetFormattedSpeechText(uid, textSanitized, speechRate, speechPitch);
return await _ttsManager.ConvertTextToSpeech(speaker, textSanitized);
}
}

Expand Down
25 changes: 14 additions & 11 deletions Content.Shared/_White/TTS/TTSPitchRateSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.Prototypes;
Expand All @@ -18,21 +17,25 @@ public sealed class TTSPitchRateSystem : EntitySystem
["Reptilian"] = new TTSPitchRate("low", "slow"),
};

public bool TryGetPitchRate(EntityUid uid, [NotNullWhen(true)] out TTSPitchRate? pitch)
public string GetFormattedSpeechText(EntityUid? uid, string text, string? speechRate = null, string? speechPitch = null)
{
if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
var ssml = text;
if (TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
{
pitch = new TTSPitchRate();
return false;
var species = SpeciesPitches.GetValueOrDefault(humanoid.Species);
if (species != null)
{
speechRate ??= species.Rate;
speechPitch ??= species.Pitch;
}
}

pitch = GetPitchRate(humanoid.Species);
return pitch != null;
}
if (speechRate != null)
ssml = $"<prosody rate=\"{speechRate}\">{ssml}</prosody>";
if (speechPitch != null)
ssml = $"<prosody pitch=\"{speechPitch}\">{ssml}</prosody>";

public TTSPitchRate? GetPitchRate(ProtoId<SpeciesPrototype> protoId)
{
return SpeciesPitches.GetValueOrDefault(protoId);
return $"<speak>{ssml}</speak>";
}
}

Expand Down
1 change: 1 addition & 0 deletions Resources/Prototypes/Entities/Mobs/Species/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@
- DoorBumpOpener
- type: Targeting
- type: SurgeryTarget
- type: TTS

- type: entity
save: false
Expand Down

0 comments on commit c5bd6b7

Please sign in to comment.