Object Tokens Overview
This document is a high level summary of Object Tokens, Categories and Registries used in SAPI. It is intended to assist developers of speech-enabled applications in understanding the concepts of tokens and categories and using them.
Token
A token is an object representing a resource. It provides an application an easy mechanism with which to inspect the various attributes of a resource without instantiating it. SAPI stores information about tokens in the registry. A token is represented in the registry by a key, and the key's underlying keys and values. For example, MSMary is a token, it represents the Microsoft Mary Voice, and its TokenId is HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices\Tokens\MSMary. Generally, a token contains a language-independent name, a CLSID used to instantiate the object from token, and a set of attributes. It may also contain a CLSID for certain types of user interfaces (UIs), and a set of files from which SAPI returns the paths to all the associated files for the token.
Categories
An Object Token Category is a class of tokens. It is represented in the registry by a key containing one or more token keys under it. Categories contain a single key called Tokens, and the keys for the tokens that belong to that category under it, or keys for token enumerators. See Object Tokens and Registry Settings for detailed descriptions of token enumerators. For example, Voice is a Category, and it contains the Microsoft Mary, Microsoft Sam, Microsoft Mike voices. Its CategoryId is HKEY_LOCAL_MACHINE\Software\Microsoft\Speech\Voices. SAPI categories that are located under HKEY_LOCAL_MACHINE\Software\Microsoft\Speech are Voices, Recognizers, AppLexicons, AudioInput, AudioOutput and PhoneConverter. Another category, Recoprofiles, is located under HKEY_CURRENT_USER\Software\Microsoft\Speech.
Using Tokens and Categories
To enumerate tokens, the application can call the ISpObjectTokenCategory::EnumTokens method, or the helper function SpEnumTokens. The following code examples demonstrate a request for female voices, using each technique. In both cases, adult voices will be listed first.
The first example calls ISpObjectTokenCategory::EnumTokens.
CComPtr<ISpObjectTokenCategory> cpCategory;
CComPtr<IEnumSpObjectTokens> cpEnum;
HRESULT hr = cpCategory.CoCreateInstance(CLSID_SpObjectTokenCategory);
//check hr
hr = cpCategory->SetId(SPCAT_VOICES, false);
//check hr
hr = cpCategory->EnumTokens(L"Gender=Female", L"Age=Adult", &cpEnum;);
//check hr
The second example calls SpEnumTokens.
CComPtr<IEnumSpObjectTokens> cpEnum;
hr = SpEnumTokens(SPCAT_VOICES, L"Gender=Female", L"Age=Adult", &cpEnum;);
// After getting enumerator, use methods in IEnumSpObjectTokens to get tokens.
CComPtr<ISpObjectToken> cpToken;
hr = cpEnum->Next(1, &cpToken;, NULL);
Other helper functions that can simplify the steps, for example: SpGetDefaultTokenFromCategoryId, SpFindBestToken. Please see the Helper Functions document for more detail descriptions.
Engine developers also need to associate files with tokens and be able to create new tokens. A token can query for all the files under the Files key using ISpObjectToken::GetStorageFileName. SAPI does not store full paths, for example:
%1c%\Microsoft\Speech\Files\MSASR\SP_63EB435D95104977BDB68E3BE3469803.dat
Use ISpObjectToken::RemoveStorageFileName to remove the files.
Keys under a token can be inspected. Following is a sample code to add a Special attribute to the default Voices token:
CComPtr<ISpObjectToken> cpToken;
CComPtr<ISpDataKey> cpKey;
hr = SpGetDefaultTokenFromCategoryId(SPCAT_VOICES, &cpToken;);
//check hr
hr = cpToken->OpenKey(L"Attributes", &cpKey;);
//check hr
hr = cpKey->SetStringValue(L"Special", L"fun");
//check hr
WCHAR *psz = NULL;
hr = cpKey->GetStringValue(L"Special", &psz;);
//check hr
::CoTaskMemFree(psz);
To create a key under default voice token, call CreateKey from the Token:
CComPtr<ISpObjectToken> cpToken;
CComPtr<ISpDataKey> cpKey;
hr = SpGetDefaultTokenFromCategoryId(SPCAT_VOICES, &cpToken;);
//check hr
hr = cpToken->CreateKey(L"CreatedKey", &cpKey;);
//check hr
hr = cpKey->SetStringValue(L"Attri", L"data");
//check hr
Detailed information can be found in Object Tokens and Registry Settings and individual API documents.