/****************************************************************************** * RegVoices.cpp * *---------------* * * This code does not ship. Based on MC's code for msttsdrv. * * This code creates the registry entries for the TTS voices. The * datafiles registered here are the ones checked in the slm source * tree. This is not done using a reg file because we need to compute * the absolute path of the datafiles which can be different on different * machines because of different root slm directories. *------------------------------------------------------------------------------ * Copyright (C) 2000 Microsoft Corporation Date: 03/20/00 * All Rights Reserved * ********************************************************************* PACOG ***/ #include #include #include "sphelper.h" #include "spddkhlp.h" #include "getopt.h" #include #include #define SYNTAX fprintf (stderr, "RegVoices [-u (UK Eng voice)] [voicesPath]\n") #define DIR_LEVELS_BACK 4 // Back levels to 'TrueTalk' directory static HRESULT CreateVoiceSubKey( const WCHAR * pszSubKeyName, const WCHAR * pszDescription, BOOL fVendorDefault, const WCHAR * pszLanguage, const WCHAR * pszGender, const WCHAR * pszAge, const WCHAR * pszVoicePath, const WCHAR * pszVoiceName, const WCHAR * pszLexPath, double dGain); const CLSID CLSID_TrueTalk = {0x8E67289A,0x609C,0x4B68,{0x91,0x8B,0x5C,0x35,0x2D,0x9E,0x5D,0x38}}; const CLSID CLSID_PhoneConverter = {0x9185F743,0x1143,0x4C28,{0x86,0xB5,0xBF,0xF1,0x4F,0x20,0xE5,0xC8}}; const WCHAR* g_UKPhoneMap = L"- 0001 ! 0002 & 0003 , 0004 . 0005 ? 0006 _ 0007 1 0008 2 0009 AA 000A AE 000B AH 000C AO 000D AW 000E AX 000F AY 0010 B 0011 CH 0012 D 0013 DH 0014 EH 0015 ER 0016 EY 0017 F 0018 G 0019 H 001A IH 001B IY 001C JH 001D K 001E L 001F M 0020 N 0021 NG 0022 OW 0023 OY 0024 P 0025 R 0026 S 0027 SH 0028 T 0029 TH 002A UH 002B UW 002C V 002D W 002E Y 002F Z 0030 ZH 0031 EX 0032 UR 0033"; //-- Static CSpUnicodeSupport g_Unicode; /***************************************************************************** * main * *-------* * Description: * Locate the abs path to Simon, etc. * and register them in the system registry. * ******************************************************************* PACOG ***/ int wmain (int argc, wchar_t* argv[]) { HRESULT hr = S_OK; WCHAR szVoiceDataPath[MAX_PATH]; WCHAR szDictDataPath[MAX_PATH]; bool fUkVoice = false; CWGetOpt getOpt; int iChar; CoInitialize(NULL); getOpt.Init(argc, argv, L"u"); while ( (iChar = getOpt.NextOption()) != EOF ) { switch (iChar) { case L'u': fUkVoice = true; break; case L'?': default: SYNTAX; goto exit; } } switch (argc - getOpt.OptInd()) { case 1: wcscpy (szVoiceDataPath, argv[getOpt.OptInd()]); wcscat (szVoiceDataPath, L"\\" ); break; case 0: //-- Get the exe's location... if( !g_Unicode.GetModuleFileName(NULL, szVoiceDataPath, MAX_PATH) ) { hr = HRESULT_FROM_WIN32(GetLastError()); } //-- ...and derive abs path to VOICE and DICT data if( SUCCEEDED(hr) ) { WCHAR *psz; // modulename is "\Src\TTS\TrueTalk\RegVoices\Obj\i386\RegVoices.exe" // data is at "\Src\TTS\TrueTalk\Voices\" for ( int i = 0; i < DIR_LEVELS_BACK; i++ ) { psz = wcsrchr( szVoiceDataPath, '\\' ); if (psz != 0) { *psz= 0; } else { hr = E_FAIL; break; } } } wcscat( szVoiceDataPath, L"\\Voices\\" ); break; default: SYNTAX; goto exit; } wcscat( wcscpy(szDictDataPath, szVoiceDataPath), L"Dict"); //-- Register the TrueTalk voices.. if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTSimonMin", L"TrueTalk Simon Min", FALSE, L"409;9", L"Male", L"Adult", szVoiceDataPath, L"Simon\\sa8kMin.sfont", szDictDataPath, 3.0); } if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTSimon150", L"TrueTalk Simon 150", FALSE, L"409;9", L"Male", L"Adult", szVoiceDataPath, L"Simon\\sa8k150.sfont", szDictDataPath, 3.0); } if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTMaryMin", L"TrueTalk Mary Min", FALSE, L"409;9", L"Female", L"Adult", szVoiceDataPath, L"Mary\\ml8kMin.sfont", szDictDataPath, 3.0); } if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTMary150", L"TrueTalk Mary 150", FALSE, L"409;9", L"Female", L"Adult", szVoiceDataPath, L"Mary\\ml8k150.sfont", szDictDataPath, 3.0); } if (fUkVoice) { if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTDianeMin", L"TrueTalk Diane Min", FALSE, L"809;9", L"Female", L"Adult", szVoiceDataPath, L"Diane\\dk8kMin.sfont", szDictDataPath, 5.0); } if( SUCCEEDED(hr) ) { hr = CreateVoiceSubKey(L"TTDiane150", L"TrueTalk Diane 150", FALSE, L"809;9", L"Female", L"Adult", szVoiceDataPath, L"Diane\\dk8k150.sfont", szDictDataPath, 5.0); } if( SUCCEEDED(hr) ) { CComPtr cpToken; CComPtr cpDataKeyAttribs; hr = SpCreateNewTokenEx( SPCAT_PHONECONVERTERS, L"English (UK)", &CLSID_PhoneConverter, L"UK English Phone Converter", 0x0, NULL, &cpToken, &cpDataKeyAttribs); if (SUCCEEDED(hr)) { hr = cpToken->SetStringValue(L"PhoneMap", g_UKPhoneMap); } if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Language", L"809"); } } } exit: CoUninitialize(); if (FAILED(hr)) { return -1; } return 0; } /***************************************************************************** * CreateVoiceSubKey * *--------------------* * Description: * Each TTS voice gets installed under one registry sub-key. * This function installs the single voice from the passed params. * ********************************************************************** MC ***/ HRESULT CreateVoiceSubKey( const WCHAR * pszSubKeyName, const WCHAR * pszDescription, BOOL fVendorDefault, const WCHAR * pszLanguage, const WCHAR * pszGender, const WCHAR * pszAge, const WCHAR * pszVoicePath, const WCHAR * pszVoiceName, const WCHAR * pszDictPath, double dGain) { HRESULT hr; CComPtr cpToken; CComPtr cpDataKeyAttribs; hr = SpCreateNewTokenEx( SPCAT_VOICES, pszSubKeyName, &CLSID_TrueTalk, pszDescription, 0x409, pszDescription, &cpToken, &cpDataKeyAttribs); if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Name", pszDescription); } if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Vendor", L"Microsoft"); } if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Language", pszLanguage); } if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Age", pszAge); } if (SUCCEEDED(hr)) { hr = cpDataKeyAttribs->SetStringValue(L"Gender", pszGender); } if (SUCCEEDED(hr) && fVendorDefault) { hr = cpDataKeyAttribs->SetStringValue(L"VendorDefault", L""); } WCHAR szVoiceDataPath[MAX_PATH]; if (SUCCEEDED(hr)) { //-------------------------------- // Voice DATA file location //-------------------------------- wcscpy(szVoiceDataPath, pszVoicePath); wcscat(szVoiceDataPath, pszVoiceName); hr = cpToken->SetStringValue(L"Sfont", szVoiceDataPath); } if (SUCCEEDED(hr)) { hr = cpToken->SetStringValue(L"Dictionary", pszDictPath); } if (SUCCEEDED(hr)) { WCHAR pszGain[20]; swprintf (pszGain, L"%.1f", dGain); hr = cpToken->SetStringValue(L"Gain", pszGain); } return hr; }