Enumerating SAPI 4 TTS engines may generate an exception or hang
Last reviewed: 10/31/2011
PRB Article ID: P101110
The information in this article applies to:
- GrammarKit 4
- LexiconKit 4
- ProfileKit 4
- SpeechKit 7
- VoiceMarkupKit 4
Symptoms
The ChantTTS class GetResourceCount method triggers TTS engine enumeration where SAPI 4 may generate an exception or hang.
Cause
SAPI 4 may be installed by programs such as Dragon Naturally Speaking. If some SAPI 4 libraries are missing, corrupted, the speech engine (i.e., recognizer or synthesizer) has errors, or there are corrupt registry entries, the SAPI 4 enumerator may throw an exception which the application may receive or on which Windows may hang.
Status
Fixed in GrammarKit build 4.0.4.0, LexiconKit build 4.0.4.0, ProfileKit build 4.0.4.0, SpeechKit build 7.0.4.0, and VoiceMarkupKit build 4.0.4.0. Other than catching the exception if returned to the application, there is nothing a SAPI 4 application can do.
To avoid the problem, the ChantGM, ChantLM, ChantPM, ChantSR, ChantTTS, and ChantVM engine API enumerators have a new optimization that allows applications to avoid enumerating SAPI 4 recognizers and synthesizers.
If you do not set any CNPEngineAPI values, the enumerators work as they always have looking on the system for all possible speech APIs.
The new enumerator enhancement allows you to set the CNPEngineAPI values for the specific speech APIs your application wants to enumerate.
After you instantiate your Chant class object, set as many CNPEngineAPI values as desired before getting the engine count and enumerating the engines.
// Enumerate Cepstral voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, (int)ChantEngineAPI.CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, (int)ChantEngineAPI.CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, (int)ChantEngineAPI.CEVAUTO);
// Set the path to the Vocalizer install path
NChantTTS1.SetStringProperty(ChantStringProperty.CSPEnginePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\");
// Set for each path to the language files
NChantTTS1.SetStringProperty(ChantStingProperty.CSPLanguagePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages");
int numberOfEngines = NChantTTS1.GetResourceCount(ChantSpeechResource.CSREngine);
for (i = 0; i < numberOfEngines; i++)
{
NChantTTSEngine nChantTTSEngine = NChantTTS1.GetChantTTSEngine(i);
// Access speech synthesis engine properties
String stringVal = nChantTTSEngine.Engine;
}
// Enumerate Cepstral voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CEVAUTO);
// Set the path to the Vocalizer install path
pChantTTS->SetStringProperty(CSPEnginePath, L"c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\");
// Set for each path to the language files
pChantTTS->SetStringProperty(CSPLanguagePath, L"c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages");
int numberOfEngines = pCChantTTS->GetResourceCount(CSREngine);
for (i = 0; i < numberOfEngines; i++)
{
CChantTTSEngine* pCChantTTSEngine = pCChantTTS->GetChantTTSEngine(i);
// Access speech synthesis engine properties
WCHAR* pszVal = pCChantTTSEngine->GetEngine();
}
// Enumerate Cepstral voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
pChantTTS->SetNumberProperty(CNPEngineAPI, CEVAUTO);
// Set the path to the Vocalizer install path
pChantTTS->SetStringProperty(CSPEnginePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\");
// Set for each path to the language files
pChantTTS->SetStringProperty(CSPLanguagePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages");
int numberOfEngines = pCChantTTS->GetResourceCount(CSREngine);
for (i = 0; i < numberOfEngines; i++)
{
CChantTTSEngine* pCChantTTSEngine = pCChantTTS->GetChantTTSEngine(i);
// Access speech synthesis engine properties
WCHAR* pszVal = pCChantTTSEngine->GetEngine();
}
var
tChantTTSEngine: TChantTTSEngine;
numberOfEngines: Integer;
i: Integer;
stringVal: string;
begin
// Enumerate Cepstral voices
ChantTTS1.SetNumberProperty(CNPEngineAPI, CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
ChantTTS1.SetNumberProperty(CNPEngineAPI, CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
ChantTTS1.SetNumberProperty(CNPEngineAPI, CEVAUTO);
// Set the path to the Vocalizer install path
ChantTTS1.SetStringProperty(CSPEnginePath, 'c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\');
// Set for each path to the language files
ChantTTS1.SetStringProperty(CSPLanguagePath, 'c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages');
numberOfEngines := ChantTTS1.GetResourceCount(CSREngine);
for i := 0 to numberOfEngines - 1 do
begin
tChantTTSEngine := ChantTTS1.GetChantTTSEngine(nIndex);
// Access speech synthesis engine properties
stringVal := tChantTTSEngine.Engine;
end;
end;
// Enumerate Cepstral voices
JChantTTS1.setNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
JChantTTS1.setNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
JChantTTS1.setNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CEVAUTO);
// Set the path to the Vocalizer install path
JChantTTS1.setStringProperty(ChantStringProperty.CSPEnginePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\");
// Set for each path to the language files
JChantTTS1.setStringProperty(ChantStingProperty.CSPLanguagePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages");
int numberOfEngines = JChantTTS1.getResourceCount(ChantSpeechResource.CSREngine);
for (i = 0; i < numberOfEngines; i++)
{
JChantTTSEngine jChantTTSEngine = JChantTTS1.getChantTTSEngine(i);
// Access speech synthesis engine properties
String stringVal = jChantTTSEngine.getEngine();
}
// Enumerate Cepstral voices
WChantTTS1.SetNumberProperty(CNPEngineAPI, CESWIFTTTS);
// Enumerate Microsoft SAPI 5 voices
WChantTTS1.SetNumberProperty(CNPEngineAPI, CESAPI5TTS);
// Enumerate Nuance Vocalizer voices
WChantTTS1.SetNumberProperty(CNPEngineAPI, CEVAUTO);
// Set the path to the Vocalizer install path
WChantTTS1.SetStringProperty(CSPEnginePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\");
// Set for each path to the language files
WChantTTS1.SetStringProperty(CSPLanguagePath, "c:\\Program Files\\Nuance\\Vocalizer for Automotive v5\\languages");
numberOfEngines = WChantTTS1.GetResourceCount(CSREngine);
for (i = 0; i < numberOfEngines; i++)
{
var wChantTTSEngine = WChantTTS1.GetResource(CSREngine, i);
// Access speech synthesis engine properties
var stringVal = wChantTTSEngine.Engine
}
Dim xChantTTSEngine As XChantTTSEngine
Dim I as Integer
Dim numberOfEngines As Integer
Dim stringVal As String
// Enumerate Cepstral voices
XChantTTS1.SetNumberProperty CNPEngineAPI, CESWIFTTTS
// Enumerate Microsoft SAPI 5 voices
XChantTTS1.SetNumberProperty CNPEngineAPI, CESAPI5TTS
// Enumerate Nuance Vocalizer voices
XChantTTS1.SetNumberProperty CNPEngineAPI, CEVAUTO
// Set the path to the Vocalizer install path
XChantTTS1.SetStringProperty CSPEnginePath, "c:\Program Files\Nuance\Vocalizer for Automotive v5\"
// Set for each path to the language files
XChantTTS1.SetStringProperty CSPLanguagePath, "c:\Program Files\Nuance\Vocalizer for Automotive v5\languages"
numberOfEngines = XChantTTS1.GetResourceCount(CSREngine);
For I = 0 To numberOfEngines - 1
Set xChantTTSEngine = XChantTTS1.GetResource(CSREngine, I)
' Access speech synthesis engine properties
stringVal = xChantTTSEngine.Engine
Next I
Dim nChantTTSEngine As NChantTTSEngine
Dim I as Integer
Dim numberOfEngines as Integer
Dim stringVal As String
' Enumerate Cepstral voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CESWIFTTTS)
' Enumerate Microsoft SAPI 5 voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CESAPI5TTS)
' Enumerate Nuance Vocalizer voices
NChantTTS1.SetNumberProperty(ChantNumberProperty.CNPEngineAPI, ChantEngineAPI.CEVAUTO)
' Set the path to the Vocalizer install path
NChantTTS1.SetStringProperty(ChantStringProperty.CSPEnginePath, "c:\Program Files\Nuance\Vocalizer for Automotive v5\")
' Set for each path to the language files
NChantTTS1.SetStringProperty(ChantStingProperty.CSPLanguagePath, "c:\Program Files\Nuance\Vocalizer for Automotive v5\languages")
numberOfEngines = NChantTTS1.GetResourceCount(ChantSpeechResource.CSREngine)
For I = 0 To numberOfEngines - 1
nChantTTSEngine = NChantTTS1.GetChantTTSEngine(i)
' Access speech synthesis engine properties
stringVal = nChantTTSEngine.Engine
Next I
Component Formats Impacted
All component formats.