Answered by:
Windows 7 64 Bit & Windows Server 2008 R2 TTS Voice Selection: Problems & Solutions

Question
-
There are multiple problems with setting a default TTS Voice in
Windows Server 2008 R2 and Windows 7 64 bit edition.
The Control Panel TTS Voice option lists only properly registered
64 bit Voices. Microsoft's Anna is the only 64 bit Voice that is
supplied with the operating systems. Loquendo's Kate, which is
probably the highest quality TTS Voice that is currently available,
has both 32 and 64 bit versions. Kate is difficult to obtain in small
quantities and is very expensive. The next best alternative is
believed to be the Acapela-Group Voice Heather. It is only
currently available in a 32 bit version for the Windows operating
systems. (64 bit Heather is available for Apple's Snow Leopard).
There is a fix that permits the display of all installed Voices and
the selection of any as the system default Voice. This is to
execute:
C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl
rather than using the Control Panel TTS Voice selection.
This fix works properly except for one unfortunate problem.
The Visual C/C++ statement
hr = m_cpVoice.CoCreateInstance( CLSID_SpVoice );
correctly sets up a Voice object regardless of the default
system Voice.
The Visual Basic statement
Voice = New SpeechLib.SpVoice
results in a system hang or program abort if the default Voice has
been set to anything other than a properly registered 64 bit Voice
like Anna. "Try Catch" doesn't catch this error. Note that
Set Voice = CreateObject("SAPI.SpVoice") also fails with the same
error.
There is no easy solution to this problem. It may, however, be less
of concern as more 64 bit TTS Voices become available.
First, Microsoft should certainly change the Control Box TTS selection
to use the same code as "C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl".
Second, Microsoft should correct the problem with the way in which
The Visual Basic statement "Voice = New SpeechLib.SpVoice" functions.
There is no reason for this not to have the same capability as its
Visual C/C++ counterpart.
Third, application programs that use TTS could be written completely
in Visual C/C++, the creation of the Voice object could be in an
Visual C ActiveX control or a wrapper could be used to access
CoCreateInstance.
Fourth, it may be possible to modify the Voice registry entries so
that 32 bit Voices work with the Control Panel TTS listing. It is
easy to modify the registry so that the Voices are displayed. There
is, however, a consistent error message regarding a failure of audio
output. The TTS registry entries are generally well documented.
Unfortunately, there are multiple entries for which there is no publicly
available documentation. This plus a lack of technical assistance from
either the third party vendors of TTS Voices or Microsoft makes it
impossible to resolve the registry entry problem at this time.
The registry issues are not a concern when you use
"C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl".
Fifth, One important reason for being able to change the system
default TTS Voice is to provide an alternate Voice choice for programs
like MapPoint which automatically select the system default Voice.
There is no other user option for changing MapPoint's Voice.
There is a MapPoint registry key at
HKEY_CURRENT_USER\Software\Microsoft\MapPoint\17.0\USA\PreferredTTSEngine
that looks as if the TTS Voice can be selected. Unfortunately, there
is no documentation for this entry and changing the Voice name doesn't
override the system default Voice.
Sixth, the registry entries could be programmatically changed so
that the default Voice meets the requirements of
"Voice = New SpeechLib.SpVoice" only for this one statement. The
original entries are then replaced prior to further usage of the
Voice object.
It is far from perfect, but we have chosen this approach as the
best current compromise for our programming environment. One
unfortunate limitation is that Windows 7 64 bit and Windows Server
2008 R2 use different TTS registry directory paths and Values for
DefaultTokenId.
Incidentally, an invaluable tool for working with the registry is
Registry Workshop for X64. It can do copy/paste in addition to
multiple other helpful registry operations.
The following code snippet demonstrates the methodology.
'Created inside Form_Load and released inside Form_Unload.
Dim WithEvents Voice As SpeechLib.SpVoice
Dim modifyRegistryFlag As Boolean = False
'Code snippet from Form_Load
Dim keyName, userRoot, subkeys, defaultString, oldString As String
Dim OSName, OSPlatform, OSVersion As String
OSName = Trim(My.Computer.Info.OSFullName.ToString)
OSPlatform = Trim(My.Computer.Info.OSPlatform.ToString)
OSVersion = Trim(My.Computer.Info.OSVersion.ToString)
If InStr(1, OSVersion, "6.1") >= 1 Then
modifyRegistryFlag = True
If InStr(1, OSName, "Microsoft Windows 7") >= 1 Then
'Registry directory path for Windows 7 64 bit
userRoot = "HKEY_CURRENT_USER"
subkeys = "Software\Microsoft\Speech\Voices"
'Default DefaultTokenId string for Windows 7 64 bit
defaultString = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MS-Anna-1033-20-DSK"
Else
If InStr(1, OSName, "Microsoft Windows Server 2008 R2") >= 1 Then
'Registry directory path for Server 2008 R2
userRoot = "HKEY_USERS"
subkeys = ".DEFAULT\Software\Microsoft\Speech\Voices"
'Default DefaultTokenId string for Server 2008 R2
defaultString = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Speech\Voices\Tokens\MS-Anna-1033-20-DSK"
End If
End If
End If
keyName = userRoot & "\" & subkeys
If modifyRegistryFlag = True Then
'Retrieve name of default Voice
oldString = ""
Try
oldString = Registry.GetValue(keyName, "DefaultTokenId", "-1")
Catch ex As Exception
MessageBox.Show(ex.Message.ToString, "TTS Error:Get Current Default Voice", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Exit Sub
End Try
If oldString = "-1" Then
MessageBox.Show("No DefaultTokenId", "TTS Error:Get Current Default Voice", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Exit Sub
End If
'Set default name to Anna if she is not the default
If oldString <> defaultString Then
'MessageBox.Show(oldString & vbCrLf & defaultString)
Try
Registry.SetValue(keyName, "DefaultTokenId", defaultString, RegistryValueKind.String)
Catch ex As Exception
MessageBox.Show(ex.Message, "TTS Error:Set Default Voice", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Exit Sub
End Try
End If
End If
'Creates the voice object
Try
Voice = New SpeechLib.SpVoice
Catch err As Exception
MessageBox.Show("Error Creating SpeechLib Voice" & vbNewLine & err.Message, "TTS Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Exit Sub
End Try
If modifyRegistryFlag = True Then
'Restore original default Voice
If oldString <> defaultString Then
Try
Registry.SetValue(keyName, "DefaultTokenId", oldString, RegistryValueKind.String)
Catch ex As Exception
MessageBox.Show(ex.Message, "TTS Error:Restore Default Voice", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
Exit Sub
End Try
End If
End If
RobbieSunday, November 15, 2009 5:42 PM
Answers
-
Since this is software development question, please discuss in our MSDN forum.
MSDN: Microsoft Development, MSDN Subscriptions, Resources, and More
Arthur Xie - MSFT- Marked as answer by Arthur Xie Friday, November 27, 2009 10:11 AM
Wednesday, November 18, 2009 3:47 AM
All replies
-
Since this is software development question, please discuss in our MSDN forum.
MSDN: Microsoft Development, MSDN Subscriptions, Resources, and More
Arthur Xie - MSFT- Marked as answer by Arthur Xie Friday, November 27, 2009 10:11 AM
Wednesday, November 18, 2009 3:47 AM -
I appear to have successfully installed Hazel and Zira Pro in Server 2008 R2 by:
1) Running SpeechPlatformRuntime32.msi
2 Installing Hazel and and Zira voices (MSSpeech_TTS_en-US_ZiraPro.msi)
3) Updating Registry to
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_en-US_ZiraPro_11.0]
@="Microsoft Server Speech Text to Speech Voice (en-US, ZiraPro)"
"409"="Microsoft Server Speech Text to Speech Voice (en-US, ZiraPro)"
"CLSID"="{a12bdfa1-c3a1-48ea-8e3f-27945e16cf7e}"
"LangDataPath"="C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Speech\\Tokens\\TTS_MS_en-US_ZiraPro_11.0\\MSTTSLocenUS.dat"
"VoicePath"="C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Speech\\Tokens\\TTS_MS_en-US_ZiraPro_11.0\\ZiraProT"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_en-US_ZiraPro_11.0\Attributes]
@=""
"Age"="Adult"
"AudioFormats"="18"
"Gender"="Female"
"Language"="409"
"Name"="Microsoft Server Speech Text to Speech Voice (en-US, ZiraPro)"
"Vendor"="Microsoft"
"Version"="11.0"
4) Changing HKEY_CURRENT_USER\Software\Microsoft\Speech\Voices to
"DefaultTokenId"="HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\TTS_MS_en-US_ZiraPro_11.0"
My Excel programs talk legibly again!
Wednesday, April 1, 2020 2:33 PM