flutter_tts icon indicating copy to clipboard operation
flutter_tts copied to clipboard

Add support for Windows 10 and 11 voices

Open Dancovich opened this issue 2 years ago • 1 comments

🚀 Feature Requests

Right now, on Windows, the library can only list voices compatible with the old TTS system (SAPI I believe). That means not all voices available on Windows 10 and 11 are available on the library.

Contextualize the feature

Windows right now is only adding voices for it's new API. Certain locales lack voices on the old API or have only voices in one gender, limiting which voices are available to the library.

Describe the feature

Add support for Windows new TTS API so the new voices are available to the library through setVoice. These voices also must be returned by getVoices.

Platforms affected (mark all that apply)

  • [X] 🪟 Windows

Dancovich avatar Jan 11 '23 21:01 Dancovich

Hi there,

I came across the same problem in our app and needed a quick solution to unblock us. I noticed that the code already includes the implementation for Microsoft SpeechSynthesis APIs but requires WINAPI_FAMILY to be defined with the correct value.

After setting the macro to WINAPI_FAMILY_APP, I encountered the following error when using the speakAsync function:

"Use of 'co_await' in this context is a non-conforming extension in C++17."

To address this issue and ensure our app works smoothly, I've made the following code changes:

#define WINAPI_FAMILY WINAPI_FAMILY_APP

void FlutterTtsPlugin::speak(const std::string text, FlutterResult result) {
    isSpeaking = true;
    create_task([&]{
        SpeechSynthesisStream speechStream = synth.SynthesizeTextToStreamAsync(to_hstring(text)).get();
        winrt::param::hstring cType = L"Audio";
        winrt::Windows::Media::Core::MediaSource source =
            winrt::Windows::Media::Core::MediaSource::CreateFromStream(speechStream, cType);
        mPlayer.Source(source);
        mPlayer.Play();
    }).get();
    methodChannel->InvokeMethod("speak.onStart", NULL);
    if (awaitSpeakCompletion) speakResult = std::move(result);
    else result->Success(1);
}

This change helped me retrieve the non-SAPI Voices successfully.

Please note that my familiarity with Windows Development is limited, so I'd appreciate any guidance or feedback on whether this solution aligns with best practices. If everything looks good, I'd be happy to assist in raising a PR.

VigneshPasupathy avatar Sep 13 '23 15:09 VigneshPasupathy