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.