I posted this earlier, but it isn't showing up on the server.
You can do it via a registry change, which can be done
programmatically on the fly as needed.
The following code shows how to do it. Note that you may have
additional voices not listed here. These are the voices I have
installed on my Windows Vista Ultimate box.
Private Declare Function RegOpenKeyEx Lib "advapi32" _
Alias "RegOpenKeyExA" ( _
ByVal HKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" ( _
ByVal HKey As Long) As Long
Private Declare Function RegSetValueExStr Lib "advapi32" _
Alias "RegSetValueExA" ( _
ByVal HKey As Long, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
ByVal szData As String, _
ByVal cbData As Long) As Long
Private Const C_MichelleKey = _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\LHMICHELLE"
Private Const C_MichaelKey = _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\LHMICHAEL"
Private Const C_AnnaKey = _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\MS-Anna-1033-20-DSK"
Private Const ERROR_SUCCESS As Long = 0&
Private Const HKCU = &H80000001
Private Const KEY_ALL_ACCESS = &H3F
Private Enum REG_DATA_TYPE
REG_INVALID = -1 ' Invalid
REG_SZ = 1 ' String
REG_DWORD = 4 ' Long
End Enum
Public Enum Voice
Michelle
Michael
Anna1033
End Enum
Sub SetVoice(WhichVoice As Voice)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SetVoice
' Set the default voice used in text to speech to LH_MICHELLE,
' LH_MICHAEL, or LH_ANNA.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim KeyName As String
Dim HKey As Long
Dim Res As Long
Select Case WhichVoice
Case Michelle
KeyName = C_MichelleKey
Case Michael
KeyName = C_MichaelKey
Case Anna1033
KeyName = C_AnnaKey
Case Else
MsgBox "Invalid Voice Identifier", vbOKOnly
Exit Sub
End Select
Res = RegOpenKeyEx(HKey:=HKCU, _
lpSubKey:="Software\Microsoft\Speech\Voices", _
ulOptions:=0&, samDesired:=KEY_ALL_ACCESS, phkResult:=HKey)
If Res <> ERROR_SUCCESS Then
MsgBox "Error openning key"
Exit Sub
End If
Res = RegSetValueExStr(HKey:=HKey, _
lpValueName:="DefaultTokenID", Reserved:=0&, _
dwType:=REG_SZ, szData:=KeyName, cbData:=Len(KeyName))
If Res <> ERROR_SUCCESS Then
MsgBox "Error setting value"
Exit Sub
End If
RegCloseKey HKey
End Sub
You can test this with:
Sub AAATest()
Dim UseVoice As Voice
Dim TextToSpeak As String
TextToSpeak = "hello world"
UseVoice = Anna1033
SetVoice UseVoice
Application.Speech.Speak TextToSpeak, False
End Sub
Change the value of UseVoice to Michael, Michelle, or Anna1033. The
text in the variable TextToSpeak will be spoken in the selected voice.
You may have additional voices installed (the three above are the only
ones I have on this machine, a Vista Ultimate box). To add support for
a new voice, go to the Start menu, choose Run, and enter RegEdit.
Navigate to the key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens
That key will contain a subkey for each installed voice, such as
LHMICHAEL and LHMICHELLE.
Suppose you find an additional subkey named LHFRANK". Create a
constant as shown below. In RegEdit, you can right-click on the
LHFRANK subkey and choose Copy Key Name to copy the full key name to
the clipboard.
Private Const C_FrankKey = _
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\LHFRANK"
Then, add Frank to the Voice enum in the code:
Public Enum Voice
Michelle
Michael
Anna1033
Frank '<<< NEW
End Enum
Then, in the SetVoice procedure, add a Case statement for Frank to the
Select Case structure:
Case Anna1033
KeyName = C_AnnaKey
Case Frank ' <<<< NEW
KeyName = C_FrankKey ' <<< NEW
With these changes in place, you can, in the example code, assign
Frank to UseVoice to get the voice defined in LHFRANK.
Cordially,
Chip Pearson
Microsoft Most Valuable Professional
Excel Product Group, 1998 - 2009
Pearson Software Consulting, LLC
www.cpearson.com
(email on web site)