Windows 10 TTS voices not showing up?
Asked Answered
T

3

7

I installed a few English language packs (US, UK and Canada) with their Speech options and I can access them in Windows 10 setting -> Speech but they doesn't show into text to speech option available from control panel and I can't use the voices with apps !

I can just use default voices which are David and Zira !

Any idea how can I use other voices ?

Tellford answered 3/11, 2016 at 16:29 Comment(0)
B
2

Windows 10 has two different TTS engines installed by default. There are the WinRT speech synthesis APIs (in the Windows.Media.SpeechSynthesis namespace), and the SAPI speech synthesis APIs (in the System.Speech.Synthesis namespace, and the COM ISpVoice interface).

David and Zira are SAPI voices; the language packs install WinRT voices.

The SAPI APIs and voices are legacy APIs, and are not being further developed; all new voices and effort are going into the WinRT APIs and voices.

If you want to use the language pack voices, you'll need to move your application over to WinRT and use the WinRT APIs.

Byyourleave answered 4/11, 2016 at 16:27 Comment(4)
Thank you for explanation, can you tell me how can I use WinRT APIs ? actually if it's possible for C# ! or a link ?!Tellford
WinRT APIs are the default when you create a Universal application in Visual Studio 2015. If the Universal app templates aren't showing up, look at the answer hereByyourleave
Is it possible to use it when creating app using C# Windows Forms Application ?Tellford
Possibly. There's a description here on how to call WinRT APIs from desktop applications. The link within the article about which APIs are callable from desktop apps seems to be stale, though.Byyourleave
S
16

I managed to fix this issue by modifying the Windows registry. In my case, under Windows 10, I installed the German language with TTS package and it installed a female voice (WinRT and SAPI) plus a male voice (WinRT only). I needed to make a desktop (not universal app) program in C# that utilized the male voice but it was not available through SAPI. So I did this "hack" and surprisingly worked right away (Windows 10 version 1803). Works for 32 and 64 bit programs (natively or WOW).

In Windows 8+ there are two speech synthesis programming interfaces (like explained by Eric Brown). But after studying the Windows registry and a couple of files referenced in there, I noticed that both APIs use the same data files so I copied the registry keys from the German male voice registered in WinRT API into the corresponding SAPI section.

Here are the detailed instructions:

  1. Open "regedit.exe".
  2. Navigate to the key

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens

There you will find each WinRT voice registered under its own key. The German male voice in my case is called MSTTS_V110_deDE_StefanM.

  1. The easiest thing is to right click the voice key (MSTTS_V110_deDE_StefanM) and from the context menu select Export to save the entire voice structure to a file (this will later allow you to easily replicate all these steps into a couple of clicks if you want to do this in another computer).

  2. Open the exported file with Notepad or similar. There you will find two key paths. Both will make a reference to the key Speech_OneCore. All you have to do is change both references from Speech_OneCore to Speech.

  3. Remove the entire line for the attributed called SayAsSupport, it is not needed by SAPI.

  4. Save your file. With the modifications it should look like this (take special notice to the key paths):

.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_deDE_StefanM]
@="Microsoft Stefan - German (Germany)"
"407"="Microsoft Stefan - German (Germany)"
"CLSID"="{179F3D56-1B0B-42B2-A962-59B7EF59FE1B}"
"LangDataPath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,\
  00,70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,\
  65,00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,\
  00,5c,00,64,00,65,00,2d,00,44,00,45,00,5c,00,4d,00,53,00,54,00,54,00,53,00,\
  4c,00,6f,00,63,00,64,00,65,00,44,00,45,00,2e,00,64,00,61,00,74,00,00,00
"VoicePath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,00,\
  70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,65,\
  00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,00,\
  5c,00,64,00,65,00,2d,00,44,00,45,00,5c,00,4d,00,31,00,30,00,33,00,31,00,53,\
  00,74,00,65,00,66,00,61,00,6e,00,00,00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MSTTS_V110_deDE_StefanM\Attributes]
"Age"="Adult"
"DataVersion"="11.0.2013.1022"
"Gender"="Male"
"Language"="407"
"Name"="Microsoft Stefan"
"SharedPronunciation"=""
"Vendor"="Microsoft"
"Version"="11.0"
  1. Embed the registry keys you created by double clicking the file.

Done! but please note that this will make the voice available through SAPI to 32 bit programs under a 32 bit version of Windows 10, OR, to 64 bit programs under a 64 bit version of Windows 10. If you want to access the voice from a 32 bit program under a 64 bit version of Windows 10 then you need to embed the corresponding keys under the WOW6432Node. To do this, simply make an extra copy of your already edited file and name it something like "my_voice_WOW.reg". Edit this new copy and now in both key paths insert another key named "WOW6432Node" between the keys SOFTWARE and Microsoft. Save your file and embed it, this should create the corresponding keys in the WOW tree-node. Your WOW file should look like this (take special notice to the key paths):

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Speech\Voices\Tokens\MSTTS_V110_deDE_StefanM]
@="Microsoft Stefan - German (Germany)"
"407"="Microsoft Stefan - German (Germany)"
"CLSID"="{179F3D56-1B0B-42B2-A962-59B7EF59FE1B}"
"LangDataPath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,\
  00,70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,\
  65,00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,\
  00,5c,00,64,00,65,00,2d,00,44,00,45,00,5c,00,4d,00,53,00,54,00,54,00,53,00,\
  4c,00,6f,00,63,00,64,00,65,00,44,00,45,00,2e,00,64,00,61,00,74,00,00,00
"VoicePath"=hex(2):25,00,77,00,69,00,6e,00,64,00,69,00,72,00,25,00,5c,00,53,00,\
  70,00,65,00,65,00,63,00,68,00,5f,00,4f,00,6e,00,65,00,43,00,6f,00,72,00,65,\
  00,5c,00,45,00,6e,00,67,00,69,00,6e,00,65,00,73,00,5c,00,54,00,54,00,53,00,\
  5c,00,64,00,65,00,2d,00,44,00,45,00,5c,00,4d,00,31,00,30,00,33,00,31,00,53,\
  00,74,00,65,00,66,00,61,00,6e,00,00,00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Speech\Voices\Tokens\MSTTS_V110_deDE_StefanM\Attributes]
"Age"="Adult"
"DataVersion"="11.0.2013.1022"
"Gender"="Male"
"Language"="407"
"Name"="Microsoft Stefan"
"SharedPronunciation"=""
"Vendor"="Microsoft"
"Version"="11.0"

Hope this helps.

Sexism answered 13/2, 2019 at 22:55 Comment(1)
Wow, this is awesome! It works! Thanks a bunch for finding this out and sharing it! Why Microsoft doesn't do this by default is beyond me. *** Also, it might be relatively easy to create a small EXE that does all the above steps automatically when executed, making all WinRT voices available as SAPI. I mean, the manual stuff works, and I was able to follow the steps, but for less technically inclined folk editing registry might seem daunting. Of course I am not suggesting that you or I would have to build this, but it's an idea that I had and thought I would share since it could help many ppl.Ouphe
B
2

Windows 10 has two different TTS engines installed by default. There are the WinRT speech synthesis APIs (in the Windows.Media.SpeechSynthesis namespace), and the SAPI speech synthesis APIs (in the System.Speech.Synthesis namespace, and the COM ISpVoice interface).

David and Zira are SAPI voices; the language packs install WinRT voices.

The SAPI APIs and voices are legacy APIs, and are not being further developed; all new voices and effort are going into the WinRT APIs and voices.

If you want to use the language pack voices, you'll need to move your application over to WinRT and use the WinRT APIs.

Byyourleave answered 4/11, 2016 at 16:27 Comment(4)
Thank you for explanation, can you tell me how can I use WinRT APIs ? actually if it's possible for C# ! or a link ?!Tellford
WinRT APIs are the default when you create a Universal application in Visual Studio 2015. If the Universal app templates aren't showing up, look at the answer hereByyourleave
Is it possible to use it when creating app using C# Windows Forms Application ?Tellford
Possibly. There's a description here on how to call WinRT APIs from desktop applications. The link within the article about which APIs are callable from desktop apps seems to be stale, though.Byyourleave
O
2

This is a c# code example for copy the Speech_OnceCore Registry entry to Speech Registry entry (to be used with System.Speech.Synthesis as SAPI Voice):

public List<string> CopySpeechRegistryEntryFromOneCore()
{
    var voices = new List<string>();
    try
    {
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens"))
        using (RegistryKey newKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Speech\Voices\Tokens", 
            RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl))
        {
            if (key != null)
            {
                var keys = key.GetSubKeyNames();
                foreach (var item in keys)
                {
                    if (newKey.OpenSubKey(item) == null)
                    {
                        RegistryKey voice = newKey.CreateSubKey(item);
                        foreach (var subKey in key.OpenSubKey(item).GetValueNames())
                        {
                            var value = key.OpenSubKey(item).GetValue(subKey);
                            if (value is string) value = (value as string).Replace(@"C:\WINDOWS", "%windir%");
                            var kind = key.OpenSubKey(item).GetValueKind(subKey);
                            voice.SetValue(subKey, value, kind);
                        }
                        foreach (var subAttribute in key.OpenSubKey(item).GetSubKeyNames())
                        {
                            RegistryKey attributes = voice.CreateSubKey(subAttribute);
                            foreach (var attribute in key.OpenSubKey(item).OpenSubKey(subAttribute).GetValueNames())
                            {
                                var value = key.OpenSubKey(item).OpenSubKey(subAttribute).GetValue(attribute);
                                var kind = key.OpenSubKey(item).OpenSubKey(subAttribute).GetValueKind(attribute);
                                if (attribute != "SayAsSupport")
                                {
                                    attributes.SetValue(attribute, value, kind);
                                }
                            }
                        }
                        voices.Add(item);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        voices.Add($"Error: {ex.Message}");
        return voices;
    }
    return voices;
}
Oldwife answered 26/3, 2021 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.