Skip to content

TTS Speech rework#7357

Open
Shivansps wants to merge 29 commits intoscp-fs2open:masterfrom
Shivansps:speech-rework
Open

TTS Speech rework#7357
Shivansps wants to merge 29 commits intoscp-fs2open:masterfrom
Shivansps:speech-rework

Conversation

@Shivansps
Copy link
Copy Markdown
Contributor

@Shivansps Shivansps commented Apr 7, 2026

The objectives of this pr are:

  1. Add TTS Speech options to ingame options settings. Incliding voice selection, voice rate, volume settings and select places were TTS is used

  2. Add TTS Speech support to Linux OS by using speech-dispatcher/libspeechd-dev, this is done used dlopen and a small implementation of the lib types. In this way there is not additional dependency for compiling or in runtime, if speech-dispatcher is not installed on host OS, the speech system just fails to init.

  3. Separate the speech system cpps into diferent files for each platform, copying the way it was done for mac, this is clearer and will make it easier to add other platforms, like android in the future.

  4. Sanitize text was moved to an earlier stage, to fsspeech.cpp, to avoid having to repeat this bit of code in every implementation.

Note:
I may have broken mac tts with these changes and i have no way to test it.

@wookieejedi wookieejedi added enhancement A new feature or upgrade of an existing feature to add additional functionality. refactor A cleanup/restructure of a feature for speed, simplicity, and/or maintainability labels Apr 7, 2026
@Sessile-Nomad
Copy link
Copy Markdown

Seconded. Also, options to increase/decrease the speed of TTS narration would be great if possible, since the default speed is slower than most people speak 🙂

@Shivansps
Copy link
Copy Markdown
Contributor Author

Seconded. Also, options to increase/decrease the speed of TTS narration would be great if possible, since the default speed is slower than most people speak 🙂

you got it

Copy link
Copy Markdown
Contributor

@notimaginative notimaginative left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it on Mac and confirmed everything was still working. Apart from the issues noted obviously. I'd like to check and test the Linux changes as well and will do that when I have a bit more time.

However, one desperately needed addition is the ability to actually test the voice changes before saving them.

Comment thread code/sound/speech_mac.mm Outdated
Comment thread code/sound/speech_mac.mm Outdated
@MjnMixael
Copy link
Copy Markdown
Contributor

Regarding testing; The options UI framework doesn't really have a nice way to set that up as a separate control.

I'd recommend carving out a special case for this option's selector to play a test whenever the value changes.

Comment thread code/sound/speech_linux.cpp Outdated
Comment thread cmake/finder/FindSpeech.cmake Outdated
Comment thread CMakeLists.txt Outdated
Comment thread code/source_groups.cmake Outdated
Comment thread code/sound/speech_linux.cpp Outdated
Comment thread code/sound/speech_linux.cpp Outdated
Comment thread code/sound/speech_linux.cpp Outdated
Comment thread code/sound/speech_linux.cpp Outdated
@notimaginative
Copy link
Copy Markdown
Contributor

Regarding testing; The options UI framework doesn't really have a nice way to set that up as a separate control.

I'd recommend carving out a special case for this option's selector to play a test whenever the value changes.

I played around with this a bit, but it doesn't look like there's a way to do it. It's easy enough to add a test command to the change listener but that's only called when changes are saved. There doesn't appear to be any current mechanism to deal with control changes when they happen.

I assume we'll have to push the test feature down the road, extend options manager to have such functionality, then circle back and add it for TTS.

@Shivansps
Copy link
Copy Markdown
Contributor Author

Shivansps commented Apr 19, 2026

I did the requested changes. taylor when you have the time please take a look. two things to add:

  1. I did remove the voice cache from mac and windows, but i had to re-add for Linux, just the brute number of voices in the included by default espeak-ng makes it impossible to even open the settings. Its not the number on the combo box thats the problem, at least not alone, its the time it takes to process them. More than 100 loops on that "for" and you will notice the delay.

  2. Regarding loading only english voices, adding another selector to do a filter is not viable rn for the same reason we cant do a voice test after changing a setting, there is no way to detect that the filter is updated so it updates the voice list.
    This also might be kind of a overkill, because you dont normally deal with this absurd number of voices in a way they all cant be listed.
    So what i did is to count them, and if there are less than 600 load them all and if there are more, only load english ones.

Also, normally you are not going to want to use the espeak-ng voices, they are terrible, so Linux users should be able to remove the espeak-ng backend and install a neural one like PiperTTS to speech-dispatcher. I havent tested that myselft but the point of using speech-dispatcher is that it should work with any TTS backend.

Comment thread code/sound/fsspeech.cpp Outdated
Comment thread code/sound/speech_win.cpp Outdated
Comment thread code/sound/speech_linux.cpp Outdated
Comment thread code/sound/speech_linux.cpp Outdated
Comment thread code/sound/fsspeech.cpp Outdated
Copy link
Copy Markdown
Contributor

@notimaginative notimaginative left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good, except for one issue that I had to confirm. The voices cache is released properly in ttsvoice_change() however that is only ever fired if the voice control changes. This means that unless the voice control is accessed the memory used by the cache is never released.

So I recommend adding a generic fsspeech_cleanup() type of function (name it what makes sense) and move the clear and shrink_to_fit calls from ttsvoice_change() to this new function. Then call that function from ingame_options_close() to release any memory used by the cache when the options screen exits.

That should resolve the final issue that I see.

(Preferably this functionality would be added to OptionsBuilder directly to allow proper cleanup, plus support an enumerator cache internally which would have made this much easier, but that is well outside the scope of this PR)

@Shivansps
Copy link
Copy Markdown
Contributor Author

Ok, added fsspeech_options_cleanup() that is called on ingame_options_close(). I checked that this is fact called on both during options saving and when there are no changes.


#include "options/OptionsManager.h"
#include "options/Option.h"
#include <sound/fsspeech.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use quotes instead of angle brackets.

An alternative to using the include here is to just add extern void fsspeech_options_cleanup(); immediately before the call to that function below. That may actually be preferred so that it's easier to remove that code in the future, assuming that the options code eventually gets modified to handle this stuff itself.

But either change works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement A new feature or upgrade of an existing feature to add additional functionality. refactor A cleanup/restructure of a feature for speed, simplicity, and/or maintainability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants