Search code examples
windows-phone-8windows-phonewindows-phone-8.1text-to-speech

Find out when Text To Speech (TTS) is completed on wp8/wp8.1


I'm trying to implement a text to speech (TTS) in my wp8 & 8.1 apps which are implemented using the mvvm pattern.

I can start the reading of the text, cancelling reading works fine but I need to find out when the text has been read as I need to reset some properties within my ViewModel i.e. IsReading/IsNotReading which are used to display/hide buttons.

I've literally have spent the last few hours going from articles to articles but to no avail. Surely there has to be a way!

I'm currently using the SpeakTextAsync and that's working fine in both wp8 and wp8.1 but does it support a way to know when it has finished reading text?

When I try to use 'SpeakSsmlAsync', which I believe supports tags/bookmarks and I thought of adding a bookmark at the end of my text and capture it in the BookmarkReached event and then reset my various ViewModel's properties but whenever I call the 'SpeakSsmlAsync' I get the following error:

An exception of type 'System.FormatException' occurred in myapp.DLL 
but was not handled in user code

WinRT information: The text associated with this error code could not 
be found.

Additional information: The text associated with this error code could 
not be found.

The text associated with this error code could not be found.

If there is a handler for this exception, the program may be safely
continued.`

It's mentioning WINRT but both apps are in Silverlight, so while the exception is not descriptive, is SpeakSsmlAsync? Any ideas what's causing this error?

Thanks.


Solution

  • SpeakTextAsync returns a task so you can wait for the task to complete in any of the standard ways. The easiest is to await it:

    private async void speak_Click(object sender, RoutedEventArgs e)
    {
        speakingState.Text = "Speaking...";
        await speechSynth.SpeakTextAsync("A quick brown fox jumps over the lazy dog");
        speakingState.Text = "... done";
    }
    

    The System.FormatException probably means that you passed invalid Ssml. You don't say what you used, but here's a working sample:

    private async void speakSsml_Click(object sender, RoutedEventArgs e)
    {
        speakingState.Text = "Speaking...";
        string speakText =
    @"<speak version=""1.0"" xmlns=""http://www.w3.org/2001/10/synthesis"" xml:lang=""en-US"">
    <s>A quick brown fox <mark name=""middle""/>  jumps over the lazy dog<mark name=""end""/></s>
    </speak>";
    
        await speechSynth.SpeakSsmlAsync(speakText);
        speakingState.Text = "... done";
    }