0

By default The text to speech engine uses an async call, this causes the main Dart thread to go on with whatever line of code comes next, this leads up to another setstate() call after the TTS speak function which reverts the animation state from Speaking to Idle almost instantly.

is there any way to avoid this issue?

I want it to work as follows:

setstate(() => _animation = 'Speaking')

wait until the TTS is finished speaking

setstate(() => _animation = 'Idle')

If I'm misunderstanding something, could you please point it out? in case this is how Dart works then if you have any workarounds that'd be great.

Simplified code for inspection:

  void _speak(String sentence) async {
    updateRiveRoot(_animation = 'Speak');
    setState(() => _isSpeaking = true);

    if (!_isSpeaking) {
      await tts.awaitSpeakCompletion(true);
      tts.speak(sentence).then((result) {
        if (result != null) {
          print("getting here");// not being preinted out
          setState(() => _isListening = false);
          setState(() => _isSpeaking = false);
          updateRiveRoot(_animation = 'Idle');
        }
      });
    } else {
      setState(() => _isSpeaking = true);
    }
    print("isSpeaking is $_isSpeaking and animation is $_animation");
  }

I have scrolled through the TTS documentation but couldn't find useful information on the problem I'm currently facing.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
abood bah
  • 154
  • 3
  • 17
  • I'm not familiar with TTS, but most asynchronous calls return a `Future` that you can wait for. If you're not already familiar with `Future`s, see: [What is a Future and how do I use it?](https://stackoverflow.com/q/63017280/). If that's not helpful, please show an example of the async call. – jamesdlin Apr 08 '21 at 23:48
  • @jamesdlin I have added a short version of what I want to do. as you can see I have the await in front of the future call, but it is being handled asynchronously then moving on on the main thread skipping the speaking animation altogether :< If you got any pointers on where I should be looking that also would be appreciated – abood bah Apr 09 '21 at 00:00
  • Are you using this plugin? https://pub.dev/packages/flutter_tts – Robert Harvey Apr 09 '21 at 20:57
  • @RobertHarvey yes, any suggestions? sorry for the cross-posting btw but I gotta submit this to my professor very soon :' – abood bah Apr 09 '21 at 20:59
  • 1
    I suggest you follow the example provided here: https://medium.com/flutterdevs/flutter-text-to-speech-3ed66ebec523 – Robert Harvey Apr 09 '21 at 21:00
  • There's also a Dart-specific example here: https://github.com/dlutton/flutter_tts/blob/master/example/lib/main.dart – Robert Harvey Apr 09 '21 at 21:02
  • In short, you need to set up at least three event handlers. I don't see you doing this in your posted code. – Robert Harvey Apr 09 '21 at 21:03

1 Answers1

0

try to use .then,

void _speak(String sentence) async {
    if (!_isSpeaking) {
      setState(() => _animation = 'Speak');
      setState(() => _isSpeaking = true);

      tts.speak(sentence).then((result) {
        if (result != null) {
          _isListening = false;
          _isSpeaking = false;
          setState((){});
        }
      });


}

 } else {
      setState(() => _isSpeaking = false);
    }
  }
Jim
  • 6,928
  • 1
  • 7
  • 18
  • thanks for the suggestion, I tried it but unfortunately the then() part didn't execute for some reason. – abood bah Apr 09 '21 at 08:17