Author Topic: Global bool variable for when TTS is active (speaking)  (Read 7503 times)

Egil Sandfeld

  • Newbie
  • *
  • Posts: 25
Global bool variable for when TTS is active (speaking)
« on: July 15, 2016, 01:34:55 AM »
Hi :)

With The DRE I'm looking to make it better and better. One of the issues out of my control is, that I sometimes have several pieces of information coming through to the driver. If one starts over another it will just cancel the first one, which is not ideal, as there might have been crucial information there.

I know there's the "Wait until speech has completed before continuing the command", but this does not factor in when other commands looking for changes in the race data suddenly triggers and stops the first TTS. It's not a fix either to have multiple TTS instance, as they will just talk on top of each other making it hard to understand anything ;)

Instead, I ask if we could have a global variable a la {TTS_ACTIVE} which is a boolean providing feedback if the TTS is speaking at the moment of the check. If this bool is true and TTS speaking, I can in other commands, make a loop to wait until the TTS_ACTIVE bool is no longer true (so not speaking anymore = audible space again to provide new feedback). This will essentially make it possible to add a speech queue system, where new pieces of information are just queued up behind each other, so when there's a lot of info to tell the driver, it will come after each other, rather than cancel each other out :)

Thanks again, Gary for a outstanding piece of software!


EDIT by Pfeil: This has been implemented as the "{STATE_TTSCOUNT}" token, which indicates how many TTS voices are speaking.
« Last Edit: April 18, 2020, 12:37:48 PM by Pfeil »

Antaniserse

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 87
    • My VA plugins
Re: Global bool variable for when TTS is active (speaking)
« Reply #1 on: July 16, 2016, 04:44:42 AM »
I may be mistaken, but a global variable like the one you describe would not always be accurate, since it has to deal with asyncrounous speech and multiple TTS instances as well, so i think it would not be always clear to VA when there's still a speech pending somewhere.

On the other hand, if you combine the "Wait until speech has completed before continuing the command" with a user variable manually set in your profile, you should be able to catch all the possible scenarios

To avoid redundand code in the profile, you can isolate the speech feedback in a single command, while the rest of the profile, instead of calling the standard TTS action, could refer to that... for example:

Define an inactive command command (sync_speech) like this
Code: [Select]
Start Loop While [PendingSpeech] Has Been Set
    Pause 0,5 seconds
End Loop
Set Boolean [PendingSpeech] to True
Say, '{TXT:LastSpeech}'  (and wait until it completes)
Set Boolean [PendingSpeech] to [Not Set]

and every time you wanna say something in all the other commands, use
Code: [Select]
Set Text [LastSpeech] to 'This is a test'
Execute command, '(sync_speech)'


Edit: also, since I've realized that your software uses a custom made plugin, not just profiles, you can achieve even greater control by integrating the speech part in the plugin itself... basic TTS capabilities in .NET could be as easy as this
Code: [Select]
using System.Speech.Synthesis;

SpeechSynthesizer synth = new SpeechSynthesizer();
synth.Speak("Hello world from the default voice.");

and you can then add any complex condition check that you'll like... again, in the profile all you need to do is just set a text variable and call a pluging function instead of the standard TTS action
« Last Edit: July 16, 2016, 04:56:18 AM by Antaniserse »
"I am not perfect and neither was my career. In the end tennis is like life, messy."
Marat Safin

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2824
Re: Global bool variable for when TTS is active (speaking)
« Reply #2 on: July 16, 2016, 01:53:26 PM »
That looks like it could be added without too much issue (famous last words).

I will add this to the backlog.

Egil Sandfeld

  • Newbie
  • *
  • Posts: 25
Re: Global bool variable for when TTS is active (speaking)
« Reply #3 on: July 18, 2016, 11:58:21 AM »
Haha, I know that feeling :D

Thanks a lot! Can you tell how long the backlog is then? It's just if I should implement a temporary solution or wait?


@Antaniserse: Wow thanks a lot man, for helping me out! Yeah the suggestion you have about making my own PendingSpeech or Speech queue is very similar to what I have in mind.

Didn't know, though, it's that easy to implement voice synthesis in .net. Will consider how it can be of use. Big thanks!

Egil Sandfeld

  • Newbie
  • *
  • Posts: 25
Re: Global bool variable for when TTS is active (speaking)
« Reply #4 on: April 08, 2019, 11:17:53 AM »
Calling Gary from his famous last words :P

In the past 3 years I have been doing OK using the idea of Antaniserse, to include a small bool that is checked before moving on to setting the bool to true, call the Say command, and then setting the bool back to false.

With the "Integrated Components" it would seem that the "Wait until speech completes before continuing command" is no longer holding back the command from continuing, as the IC immediately calls the Say command line to be completed. Is it possible to do one of the following:

  • Provide a TTSACTIVE state toggle like suggested 3 years ago
  • Handle async calls with "Wait until speech completes before continuing command" so it won't continue before the say command line actually completes

I don't want to do a fixed cool-down period of for example setting the bool to true, for 5 seconds and then setting is to false, as this prevents a nice flow of short messages, and because it will cut longer messages.

Big thanks again for making VA! It's awesome :D

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2824
Re: Global bool variable for when TTS is active (speaking)
« Reply #5 on: April 08, 2019, 11:32:35 AM »
Quote
With the "Integrated Components" it would seem that the "Wait until speech completes before continuing command" is no longer holding back the command from continuing

Are you saying that your commands are continuing before the speaking is finished (Nothing has changed in this section of code in some time)?

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4759
  • RTFM
Re: Global bool variable for when TTS is active (speaking)
« Reply #6 on: April 08, 2019, 02:13:37 PM »
I tested using these commands:

monitor bool
Code: [Select]
Execute command, 'speak tts'
Start Loop While : [tts] Equals False
End Loop
Write [Blue] 'Speech start {TIME}:{TIMESECOND}' to log
Start Loop While : [tts] Equals True
End Loop
Write [Blue] 'Speech end {TIME}:{TIMESECOND}' to log

speak tts
Code: [Select]
Write [Blue] 'start {TIME}:{TIMESECOND}' to log
Set Boolean [tts] to True
Say, 'This will take the text-to-speech engine a few moments to speak. At the default rate of 0, it takes Microsoft David about 10 seconds.'  (and wait until it completes)
Set Boolean [tts] to False
Write [Blue] 'end {TIME}:{TIMESECOND}' to log

As the text says, it takes about 10 seconds between the respective "start" and "end" log entries(on my system).

I'm not sure what you mean by "async calls", but I had the first command run the second asynchronously(with the "Wait until this command completes before continuing" option unchecked), which works as expected.


Are you using any plugins? EDDI, perhaps?

Egil Sandfeld

  • Newbie
  • *
  • Posts: 25
Re: Global bool variable for when TTS is active (speaking)
« Reply #7 on: April 13, 2019, 02:02:48 AM »
Thanks guys, I think I wrapped my head around it.