PLEASE HELP! Application.speech - Everyone always ignores thisquestion

M

Michelle

Hello, I have asked this before, I guess no one knows the answer...

I want to use the speech facility to read out cells, but I need to
ensure that the right voice is used.

What is the code to make it switch to a particular voice e.g.
"Microsoft Sam" or "Michelle"

I really hope someone can help..

Michelle
 
P

Patrick Molloy

this is really a Windows O/S or Vista O/S question. There's no VBA code per
se for this, though I'm sure that there's an API that would allow you to do
this. I'm not an API guy, I'm sorry.
 
C

Chip Pearson

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)
 
C

Chip Pearson

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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top