diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/text-to-speech/windows/sphelper-scummvm.h | 2296 | ||||
| -rw-r--r-- | backends/text-to-speech/windows/windows-text-to-speech.cpp | 70 | 
2 files changed, 42 insertions, 2324 deletions
diff --git a/backends/text-to-speech/windows/sphelper-scummvm.h b/backends/text-to-speech/windows/sphelper-scummvm.h deleted file mode 100644 index 3fc7772d98..0000000000 --- a/backends/text-to-speech/windows/sphelper-scummvm.h +++ /dev/null @@ -1,2296 +0,0 @@ -// To get sphelper.h working with MinGW, several changes had to be made -// -// SUMMARY OF CHANGES: -// 1. Unneeded functions got deleted -//       SpCreateObjectFromToken -//       SpCreateObjectFromTokenId -//       SpCreateDefaultObjectFromCategoryId -//       SpCreateBestObject -//       SpCreatePhoneConverter -//       SpBindToFile -//       CreatePhraseFromWordArray -//       CreatePhraseFromText -// -// 2. Unneeded includes got deleted -//       crtdbg.h -//       SPDebug.h -//       atlbase.h -//       sapiddk.h -// -// 3. Include got added -//       cwtype -// -// 4. Calls to SPDBG_ASSERT() got deleted -// 5. CComPtr<> were replaced by plain C style pointers and code that works with -//	  these was adjusted accordingly -//  -// More small changes were made throughout the whole file. The best way to -// see all changes is probably to diff this and the original file. -/******************************************************************************* -* SPHelper.h * -*------------* -*   Description: -*       This is the header file for core helper functions implementation. -*------------------------------------------------------------------------------- -*   Copyright (c) Microsoft Corporation. All rights reserved. -*******************************************************************************/ -#ifndef SPHelper_h -#define SPHelper_h - -#include <iostream> -#ifndef _INC_MALLOC -#include <malloc.h> -#endif - -#ifndef __sapi_h__ -#include <sapi.h> -#endif - -#ifndef SPError_h -#include <sperror.h> -#endif - -#ifndef _INC_LIMITS -#include <limits.h> -#endif - -#ifndef _INC_MMSYSTEM -#include <mmsystem.h> -#endif - -#ifndef __comcat_h__ -#include <comcat.h> -#endif - -#ifndef _INC_MMREG -#include <mmreg.h> -#endif - -#include <cwctype> -//=== Constants ============================================================== -#define sp_countof(x) ((sizeof(x) / sizeof(*(x)))) - -/*** CSpDynamicString helper class -* -*/ -class CSpDynamicString  -{ -public: - -    WCHAR *     m_psz; -    CSpDynamicString() -    { -        m_psz = NULL; -    } -    CSpDynamicString(ULONG cchReserve) -    { -        m_psz = (WCHAR *)::CoTaskMemAlloc(cchReserve * sizeof(WCHAR)); -    } -    WCHAR * operator=(const CSpDynamicString& src) -    { -        if (m_psz != src.m_psz) -        { -            ::CoTaskMemFree(m_psz); -            m_psz = src.Copy(); -        } -        return m_psz; -    } -    WCHAR * operator=(const WCHAR * pSrc) -    { -        Clear(); -        if (pSrc) -        { -            ULONG cbNeeded = (wcslen(pSrc) + 1) * sizeof(WCHAR); -            m_psz = (WCHAR *)::CoTaskMemAlloc(cbNeeded); -            if (m_psz) -            { -                memcpy(m_psz, pSrc, cbNeeded);     -            } -        } -        return m_psz; -    } - -    WCHAR * operator=(const char * pSrc) -    { -        Clear(); -        if (pSrc) -        { -            ULONG cbNeeded = (lstrlenA(pSrc) + 1) * sizeof(WCHAR); -            m_psz = (WCHAR *)::CoTaskMemAlloc(cbNeeded); -            if (m_psz) -            { -                ::MultiByteToWideChar(CP_ACP, 0, pSrc, -1, m_psz, cbNeeded/sizeof(WCHAR)); -            } -        } -        return m_psz; -    } - -    WCHAR * operator=(REFGUID rguid) -    { -        Clear(); -        ::StringFromCLSID(rguid, &m_psz); -        return m_psz; -    } - - -    /*explicit*/ CSpDynamicString(const WCHAR * pSrc) -    { -        m_psz = NULL; -        operator=(pSrc); -    } -    /*explicit*/ CSpDynamicString(const char * pSrc) -    { -        m_psz = NULL; -        operator=(pSrc); -    } -    /*explicit*/ CSpDynamicString(const CSpDynamicString& src) -    { -        m_psz = src.Copy(); -    } -    /*explicit*/ CSpDynamicString(REFGUID rguid) -    { -        ::StringFromCLSID(rguid, &m_psz); -    } - - -    ~CSpDynamicString() -    { -        ::CoTaskMemFree(m_psz); -    } -    unsigned int Length() const -    { -        return (m_psz == NULL)? 0 : wcslen(m_psz); -    } - -    operator WCHAR * () const -    { -        return m_psz; -    } -    //The assert on operator& usually indicates a bug.  If this is really -    //what is needed, however, take the address of the m_psz member explicitly. -    WCHAR ** operator&() -    { -        return &m_psz; -    } - -    WCHAR * Append(const WCHAR * pszSrc) -    { -        if (pszSrc) -        { -            ULONG lenSrc = wcslen(pszSrc); -            if (lenSrc) -            { -                ULONG lenMe = Length(); -                WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc + 1) * sizeof(WCHAR)); -                if (pszNew) -                { -                    if (m_psz)  // Could append to an empty string so check... -                    { -                        if (lenMe) -                        { -                            memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR)); -                        } -                        ::CoTaskMemFree(m_psz); -                    } -                    memcpy(pszNew + lenMe, pszSrc, (lenSrc + 1) * sizeof(WCHAR)); -                    m_psz = pszNew; -                } -                else -                { -                } -            } -        } -        return m_psz; -    } - -    WCHAR * Append(const WCHAR * pszSrc, const ULONG lenSrc) -    { -        if (pszSrc && lenSrc) -        { -            ULONG lenMe = Length(); -            WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc + 1) * sizeof(WCHAR)); -            if (pszNew) -            { -                if (m_psz)  // Could append to an empty string so check... -                { -                    if (lenMe) -                    { -                        memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR)); -                    } -                    ::CoTaskMemFree(m_psz); -                } -                memcpy(pszNew + lenMe, pszSrc, lenSrc * sizeof(WCHAR)); -                *(pszNew + lenMe + lenSrc) = L'\0'; -                m_psz = pszNew; -            } -            else -            { -            } -        } -        return m_psz; -    } - -    WCHAR * Append2(const WCHAR * pszSrc1, const WCHAR * pszSrc2) -    { -        ULONG lenSrc1 = pszSrc1 ? wcslen(pszSrc1) : 0; -        ULONG lenSrc2 = pszSrc2 ? wcslen(pszSrc2) : 0; - -        if (lenSrc1 || lenSrc2) -        { -            ULONG lenMe = Length(); -            WCHAR *pszNew = (WCHAR *)::CoTaskMemAlloc((lenMe + lenSrc1 + lenSrc2 + 1) * sizeof(WCHAR)); -            if (pszNew) -            { -                if (m_psz)  // Could append to an empty string so check... -                { -                    if (lenMe) -                    { -                        memcpy(pszNew, m_psz, lenMe * sizeof(WCHAR)); -                    } -                    ::CoTaskMemFree(m_psz); -                } -                // In both of these cases, we copy the trailing NULL so that we're sure it gets -                // there (if lenSrc2 is 0 then we better copy it from pszSrc1). -                if (lenSrc1) -                { -                    memcpy(pszNew + lenMe, pszSrc1, (lenSrc1 + 1) * sizeof(WCHAR)); -                } -                if (lenSrc2) -                { -                    memcpy(pszNew + lenMe + lenSrc1, pszSrc2, (lenSrc2 + 1) * sizeof(WCHAR)); -                } -                m_psz = pszNew; -            } -            else -            { -            } -        } -        return m_psz; -    } -    WCHAR * Copy() const -    { -        if (m_psz) -        { -            CSpDynamicString szNew(m_psz); -            return szNew.Detach(); -        } -        return NULL; -    } -    CHAR * CopyToChar() const -    { -        if (m_psz) -        { -            CHAR* psz; -            ULONG cbNeeded = ::WideCharToMultiByte(CP_ACP, 0, m_psz, -1, NULL, NULL, NULL, NULL); -            psz = (CHAR *)::CoTaskMemAlloc(cbNeeded); -            if (psz) -            { -                ::WideCharToMultiByte(CP_ACP, 0, m_psz, -1, psz, cbNeeded/sizeof(CHAR), NULL, NULL); -            } -            return psz; -        } -        return NULL; -    } -    void Attach(WCHAR * pszSrc) -    { -        m_psz = pszSrc; -    } -    WCHAR * Detach() -    { -        WCHAR * s = m_psz; -        m_psz = NULL; -        return s; -    } -    void Clear() -    { -        ::CoTaskMemFree(m_psz); -        m_psz = NULL; -    } -    bool operator!() const -    { -        return (m_psz == NULL); -    } -    HRESULT CopyToBSTR(BSTR * pbstr) -    { -        if (m_psz) -        { -            *pbstr = ::SysAllocString(m_psz); -            if (*pbstr == NULL) -            { -                return E_OUTOFMEMORY; -            } -        } -        else -        { -            *pbstr = NULL; -        } -        return S_OK; -    } -    void TrimToSize(ULONG ulNumChars) -    { -        if (m_psz && ulNumChars < Length()) -        { -            m_psz[ulNumChars] = 0; -        } -    } -    WCHAR * Compact() -    { -        if (m_psz) -        { -            ULONG cch = wcslen(m_psz); -            m_psz = (WCHAR *)::CoTaskMemRealloc(m_psz, (cch + 1) * sizeof(WCHAR)); -        } -        return m_psz; -    } -    WCHAR * ClearAndGrowTo(ULONG cch) -    { -        if (m_psz) -        { -            Clear(); -        } -        m_psz = (WCHAR *)::CoTaskMemAlloc(cch * sizeof(WCHAR)); -        return m_psz; -    } -    WCHAR * LTrim() -    { -        if (m_psz) -        { -            WCHAR * pszRead = m_psz; -            while (iswspace(*pszRead)) -            { -                pszRead++; -            } -            if (pszRead != m_psz) -            { -                WCHAR * pszWrite = m_psz; -                while (*pszRead) -                { -                    *pszWrite++ = *pszRead++; -                } -                *pszWrite = '\0'; -            } -        } -        return m_psz; -    } -    WCHAR * RTrim() -    { -        if (m_psz) -        { -            WCHAR * pszTail = m_psz + wcslen(m_psz); -            WCHAR * pszZeroTerm = pszTail; -            while (pszZeroTerm > m_psz && iswspace(pszZeroTerm[-1])) -            { -                pszZeroTerm--; -            } -            if (pszZeroTerm != pszTail) -            { -                *pszZeroTerm = '\0'; -            } -        } -        return m_psz;         -    } -    WCHAR * TrimBoth() -    { -        RTrim(); -        return LTrim(); -    } -}; - - - -// -//  Simple inline function converts a ulong to a hex string. -// -inline void SpHexFromUlong(WCHAR * psz, ULONG ul) -{ -    const static WCHAR szHexChars[] = L"0123456789ABCDEF"; -    if (ul == 0) -    { -        psz[0] = L'0'; -        psz[1] = 0; -    } -    else -    { -        ULONG ulChars = 1; -        psz[0] = 0; -        while (ul) -        { -            memmove(psz + 1, psz, ulChars * sizeof(WCHAR)); -            psz[0] = szHexChars[ul % 16]; -            ul /= 16; -            ulChars++; -        } -    } -} - - -//=== Token helpers - -inline HRESULT SpGetTokenFromId( -    const WCHAR * pszTokenId,  -    ISpObjectToken ** ppToken, -    BOOL fCreateIfNotExist = FALSE) -{ -     -    LPUNKNOWN pUnkOuter = nullptr; -    HRESULT hr = ::CoCreateInstance(CLSID_SpObjectToken, pUnkOuter, CLSCTX_ALL, IID_ISpObjectToken,reinterpret_cast<void **>(ppToken)); -     -    if (SUCCEEDED(hr)) -    { -        (*ppToken)->SetId(NULL, pszTokenId, fCreateIfNotExist); -    } -     -    return hr; -} - -inline HRESULT SpGetCategoryFromId( -    const WCHAR * pszCategoryId, -    ISpObjectTokenCategory ** ppCategory, -    BOOL fCreateIfNotExist = FALSE) -{ -    LPUNKNOWN pUnkOuter = nullptr; -    HRESULT hr = ::CoCreateInstance(CLSID_SpObjectTokenCategory, pUnkOuter, CLSCTX_ALL, IID_ISpObjectTokenCategory, reinterpret_cast<void **>(ppCategory)); -     -    if (SUCCEEDED(hr)) -    { -        hr = (*ppCategory)->SetId(pszCategoryId, fCreateIfNotExist); -    } -     -    return hr; -} - -inline HRESULT SpGetDefaultTokenIdFromCategoryId( -    const WCHAR * pszCategoryId, -    WCHAR ** ppszTokenId) -{ -    HRESULT hr; - -    ISpObjectTokenCategory *cpCategory; -    hr = SpGetCategoryFromId(pszCategoryId, &cpCategory); -     -    if (SUCCEEDED(hr)) -    { -        hr = cpCategory->GetDefaultTokenId(ppszTokenId); -    } - -    return hr; -} - -inline HRESULT SpSetDefaultTokenIdForCategoryId( -    const WCHAR * pszCategoryId, -    const WCHAR * pszTokenId) -{ -    HRESULT hr; - -    ISpObjectTokenCategory *cpCategory; -    hr = SpGetCategoryFromId(pszCategoryId, &cpCategory); -     -    if (SUCCEEDED(hr)) -    { -        hr = cpCategory->SetDefaultTokenId(pszTokenId); -    } - -    return hr; -} - -inline HRESULT SpGetDefaultTokenFromCategoryId( -    const WCHAR * pszCategoryId, -    ISpObjectToken ** ppToken, -    BOOL fCreateCategoryIfNotExist = TRUE) -{ -    HRESULT hr; - -    ISpObjectTokenCategory *cpCategory; -    hr = SpGetCategoryFromId(pszCategoryId, &cpCategory, fCreateCategoryIfNotExist); - -    if (SUCCEEDED(hr)) -    { -        WCHAR * pszTokenId; -        hr = cpCategory->GetDefaultTokenId(&pszTokenId); -        if (SUCCEEDED(hr)) -        { -            hr = SpGetTokenFromId(pszTokenId, ppToken); -            ::CoTaskMemFree(pszTokenId); -        } -    } - -    return hr; -} - -inline HRESULT SpSetDefaultTokenForCategoryId( -    const WCHAR * pszCategoryId, -    ISpObjectToken * pToken) -{ -    HRESULT hr; - -    WCHAR * pszTokenId; -    hr = pToken->GetId(&pszTokenId); - -    if (SUCCEEDED(hr)) -    { -        hr = SpSetDefaultTokenIdForCategoryId(pszCategoryId, pszTokenId); -        ::CoTaskMemFree(pszTokenId); -    } - -    return hr; -} - -inline HRESULT SpSetCommonTokenData( -    ISpObjectToken * pToken, -    const CLSID * pclsid, -    const WCHAR * pszLangIndependentName, -    LANGID langid, -    const WCHAR * pszLangDependentName, -    ISpDataKey ** ppDataKeyAttribs) -{ -    HRESULT hr = S_OK; -     -    // Set the new token's CLSID (if specified) -    if (SUCCEEDED(hr) && pclsid) -    { -        CSpDynamicString dstrClsid; -        hr = StringFromCLSID(*pclsid, &dstrClsid); -     -        if (SUCCEEDED(hr)) -        { -            hr = pToken->SetStringValue(SPTOKENVALUE_CLSID, dstrClsid); -        } -    } - -    // Set the token's lang independent name -    if (SUCCEEDED(hr) && pszLangIndependentName) -    { -        hr = pToken->SetStringValue(NULL, pszLangIndependentName); -    } - -    // Set the token's lang dependent name -    if (SUCCEEDED(hr) && pszLangDependentName) -    { -	    WCHAR szLangId[10]; -	    SpHexFromUlong(szLangId, langid); -	     -        hr = pToken->SetStringValue(szLangId, pszLangDependentName); -    } - -    // Open the attributes key if requested -    if (SUCCEEDED(hr) && ppDataKeyAttribs) -    { -        hr = pToken->CreateKey(L"Attributes", ppDataKeyAttribs); -    } - -    return hr; -} - -inline HRESULT SpCreateNewToken( -    const WCHAR * pszTokenId, -    ISpObjectToken ** ppToken) -{ -    HRESULT hr; - -    // Forcefully create the token -    hr = SpGetTokenFromId(pszTokenId, ppToken, TRUE); -     -    return hr; -} - -inline HRESULT SpCreateNewToken( -    const WCHAR * pszCategoryId, -    const WCHAR * pszTokenKeyName, -    ISpObjectToken ** ppToken) -{ -    HRESULT hr; - -    // Forcefully create the category -    ISpObjectTokenCategory *cpCategory; -    hr = SpGetCategoryFromId(pszCategoryId, &cpCategory, TRUE); - -    // Come up with a token key name if one wasn't specified -    CSpDynamicString dstrTokenKeyName; -    if (SUCCEEDED(hr)) -    { -        if (pszTokenKeyName == NULL) -        { -            GUID guidTokenKeyName; -            hr = CoCreateGuid(&guidTokenKeyName); - -            if (SUCCEEDED(hr)) -            { -                hr = StringFromCLSID(guidTokenKeyName, &dstrTokenKeyName); -            } - -            if (SUCCEEDED(hr)) -            { -                pszTokenKeyName = dstrTokenKeyName; -            } -        } -    } - -    // Build the token id -    CSpDynamicString dstrTokenId; -    if (SUCCEEDED(hr)) -    { -        dstrTokenId = pszCategoryId; -        dstrTokenId.Append2(L"\\Tokens\\", pszTokenKeyName); -    } - -    // Forcefully create the token -    if (SUCCEEDED(hr)) -    { -        hr = SpGetTokenFromId(dstrTokenId, ppToken, TRUE); -    } -     -    return hr; -} - -inline HRESULT SpCreateNewTokenEx( -    const WCHAR * pszCategoryId, -    const WCHAR * pszTokenKeyName, -    const CLSID * pclsid, -    const WCHAR * pszLangIndependentName, -    LANGID langid, -    const WCHAR * pszLangDependentName, -    ISpObjectToken ** ppToken, -    ISpDataKey ** ppDataKeyAttribs) -{ -    HRESULT hr; - -    // Create the new token -    hr = SpCreateNewToken(pszCategoryId, pszTokenKeyName, ppToken); - -    // Now set the extra data -    if (SUCCEEDED(hr)) -    { -        hr = SpSetCommonTokenData( -                    *ppToken,  -                    pclsid,  -                    pszLangIndependentName,  -                    langid,  -                    pszLangDependentName,  -                    ppDataKeyAttribs); -    } -     -    return hr; -} - -inline HRESULT SpCreateNewTokenEx( -    const WCHAR * pszTokenId, -    const CLSID * pclsid, -    const WCHAR * pszLangIndependentName, -    LANGID langid, -    const WCHAR * pszLangDependentName, -    ISpObjectToken ** ppToken, -    ISpDataKey ** ppDataKeyAttribs) -{ -    HRESULT hr; - -    // Create the new token -    hr = SpCreateNewToken(pszTokenId, ppToken); - -    // Now set the extra data -    if (SUCCEEDED(hr)) -    { -        hr = SpSetCommonTokenData( -                    *ppToken,  -                    pclsid,  -                    pszLangIndependentName,  -                    langid,  -                    pszLangDependentName,  -                    ppDataKeyAttribs); -    } -     -    return hr; -} - -inline HRESULT SpEnumTokens( -    const WCHAR * pszCategoryId,  -    const WCHAR * pszReqAttribs,  -    const WCHAR * pszOptAttribs,  -    IEnumSpObjectTokens ** ppEnum) -{ -    HRESULT hr = S_OK; -     -    ISpObjectTokenCategory *cpCategory; -    hr = SpGetCategoryFromId(pszCategoryId, &cpCategory); -     -    if (SUCCEEDED(hr)) -    { -        hr = cpCategory->EnumTokens( -                    pszReqAttribs, -                    pszOptAttribs, -                    ppEnum); -    } -     -    return hr; -} - -inline HRESULT SpFindBestToken( -    const WCHAR * pszCategoryId,  -    const WCHAR * pszReqAttribs,  -    const WCHAR * pszOptAttribs,  -    ISpObjectToken **ppObjectToken) -{ -    HRESULT hr = S_OK; -     -    const WCHAR *pszVendorPreferred = L"VendorPreferred"; -    const unsigned long LenVendorPreferred = wcslen(pszVendorPreferred); - -    // append VendorPreferred to the end of pszOptAttribs to force this preference -    ULONG ulLen = pszOptAttribs ? wcslen(pszOptAttribs) + LenVendorPreferred + 1 : LenVendorPreferred; -    WCHAR *pszOptAttribsVendorPref = (WCHAR*)_alloca((ulLen+1)*sizeof(WCHAR)); -    if (pszOptAttribsVendorPref) -    { -        if (pszOptAttribs) -        { -            wcscpy(pszOptAttribsVendorPref, pszOptAttribs); -            wcscat(pszOptAttribsVendorPref, L";"); -            wcscat(pszOptAttribsVendorPref, pszVendorPreferred); -        } -        else -        { -            wcscpy(pszOptAttribsVendorPref, pszVendorPreferred); -        } -    } -    else -    { -        hr = E_OUTOFMEMORY; -    } - -    IEnumSpObjectTokens *cpEnum; -    if (SUCCEEDED(hr)) -    { -        hr = SpEnumTokens(pszCategoryId, pszReqAttribs, pszOptAttribsVendorPref, &cpEnum); -    } - -    if (SUCCEEDED(hr)) -    { -        hr = cpEnum->Next(1, ppObjectToken, NULL); -        if (hr == S_FALSE) -        { -            *ppObjectToken = NULL; -            hr = SPERR_NOT_FOUND; -        } -    } - -    if (hr != SPERR_NOT_FOUND) -    { -    } -     -    return hr; -} - - -/**************************************************************************** -* SpHrFromWin32 * -*---------------* -*   Description: -*       This inline function works around a basic problem with the macro -*   HRESULT_FROM_WIN32.  The macro forces the expresion in ( ) to be evaluated -*   two times.  By using this inline function, the expression will only be -*   evaluated once. -* -*   Returns: -*       HRESULT of converted Win32 error code -* -*****************************************************************************/ - -inline HRESULT SpHrFromWin32(DWORD dwErr) -{ -    return HRESULT_FROM_WIN32(dwErr); -} - - -/**************************************************************************** -* SpHrFromLastWin32Error * -*------------------------* -*   Description: -*       This simple inline function is used to return a converted HRESULT -*   from the Win32 function ::GetLastError.  Note that using HRESULT_FROM_WIN32 -*   will evaluate the error code twice so we don't want to use: -* -*       HRESULT_FROM_WIN32(::GetLastError())  -* -*   since that will call GetLastError twice. -*   On Win98 and WinMe ::GetLastError() returns 0 for some functions (see MSDN). -*   We therefore check for that and return E_FAIL. This function should only be -*   called in an error case since it will always return an error code! -* -*   Returns: -*       HRESULT for ::GetLastError() -* -*****************************************************************************/ - -inline HRESULT SpHrFromLastWin32Error() -{ -    DWORD dw = ::GetLastError(); -    return (dw == 0) ? E_FAIL : SpHrFromWin32(dw); -} - - -/**************************************************************************** -* SpGetUserDefaultUILanguage * -*----------------------------* -*   Description: -*       Returns the default user interface language, using a method  -*       appropriate to the platform (Windows 9x, Windows NT, or Windows 2000) -* -*   Returns: -*       Default UI language -* -*****************************************************************************/ - -inline LANGID SpGetUserDefaultUILanguage(void)  -{ -    HRESULT hr = S_OK; -    LANGID wUILang = 0; - -    OSVERSIONINFO Osv ; -    Osv.dwOSVersionInfoSize = sizeof(Osv) ; -    if(!GetVersionEx(&Osv))  -    { -        hr = SpHrFromLastWin32Error(); -    } -    // Get the UI language by one of three methods, depending on the system -    else if(Osv.dwPlatformId != VER_PLATFORM_WIN32_NT)  -    { -        // Case 1: Running on Windows 9x. Get the system UI language from registry: -        CHAR szData[32]; -        DWORD dwSize = sizeof(szData) ; -        HKEY hKey; - -        long lRet = RegOpenKeyEx( -                        HKEY_USERS,  -                        ".Default\\Control Panel\\desktop\\ResourceLocale",  -                        0,  -                        KEY_READ,  -                        &hKey); - -#ifdef _WIN32_WCE_BUG_10655 -        if (lRet == ERROR_INVALID_PARAMETER) -        { -            lRet = ERROR_FILE_NOT_FOUND; -        } -#endif // _WIN32_WCE_BUG_10655 - -        hr = SpHrFromWin32(lRet); - -        if (SUCCEEDED(hr)) -        { -            lRet = RegQueryValueEx(   -                        hKey,  -                        "",  -                        NULL,  -                        NULL,  -                        (BYTE *)szData,  -                        &dwSize); - -#ifdef _WIN32_WCE_BUG_10655 -            if(lRet == ERROR_INVALID_PARAMETER) -            { -                lRet = ERROR_FILE_NOT_FOUND; -            } -#endif //_WIN32_WCE_BUG_10655 - -            hr = SpHrFromWin32(lRet);  -            ::RegCloseKey(hKey) ; -        } -        if (SUCCEEDED(hr)) -        { -            // Convert string to number -            wUILang = (LANGID) strtol(szData, NULL, 16) ; -        } -    } -    else if (Osv.dwMajorVersion >= 5.0)  -    { -    // Case 2: Running on Windows 2000 or later. Use GetUserDefaultUILanguage to find  -    // the user's prefered UI language - - -        HMODULE hMKernel32 = ::LoadLibraryW(L"kernel32.dll") ; -        if (hMKernel32 == NULL) -        { -            hr = SpHrFromLastWin32Error(); -        } -        else -        { - -            LANGID (WINAPI *pfnGetUserDefaultUILanguage) () =  -                (LANGID (WINAPI *)(void))  -#ifdef _WIN32_WCE -                    GetProcAddress(hMKernel32, L"GetUserDefaultUILanguage") ; -#else -                    GetProcAddress(hMKernel32, "GetUserDefaultUILanguage") ; -#endif - -            if(NULL != pfnGetUserDefaultUILanguage)  -            { -                wUILang = pfnGetUserDefaultUILanguage() ; -            } -            else -            {   // GetProcAddress failed -                hr = SpHrFromLastWin32Error(); -            } -            ::FreeLibrary(hMKernel32); -        } -    } -    else { -    // Case 3: Running on Windows NT 4.0 or earlier. Get UI language -    // from locale of .default user in registry: -    // HKEY_USERS\.DEFAULT\Control Panel\International\Locale -         -        WCHAR szData[32]   ; -        DWORD dwSize = sizeof(szData) ; -        HKEY hKey          ; - -        LONG lRet = RegOpenKeyEx(HKEY_USERS,  -                                    ".DEFAULT\\Control Panel\\International",  -                                    0,  -                                    KEY_READ,  -                                    &hKey); -#ifdef _WIN32_WCE_BUG_10655 -            if(lRet == ERROR_INVALID_PARAMETER) -            { -                lRet = ERROR_FILE_NOT_FOUND; -            } -#endif //_WIN32_WCE_BUG_10655 - -        hr = SpHrFromWin32(lRet); - -        if (SUCCEEDED(hr)) -        { -            lRet = RegQueryValueEx(   -                        hKey,  -                        "Locale", -                        NULL,  -                        NULL,  -                        (BYTE *)szData,  -                        &dwSize); - -#ifdef _WIN32_WCE_BUG_10655 -            if(lRet == ERROR_INVALID_PARAMETER) -            { -                lRet = ERROR_FILE_NOT_FOUND; -            } -#endif //_WIN32_WCE_BUG_10655 - -        hr = SpHrFromWin32(lRet); -            ::RegCloseKey(hKey); -        } - -        if (SUCCEEDED(hr)) -        { -            // Convert string to number -            wUILang = (LANGID) wcstol(szData, NULL, 16) ; - -            if(0x0401 == wUILang || // Arabic -               0x040d == wUILang || // Hebrew -               0x041e == wUILang    // Thai -               ) -            { -                // Special case these to the English UI. -                // These versions of Windows NT 4.0 were enabled only, i.e., the -                // UI was English. However, the registry setting  -                // HKEY_USERS\.DEFAULT\Control Panel\International\Locale was set   -                // to the respective locale for application compatibility. -                wUILang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US) ; -            } -        } -    } - -    return (wUILang ? wUILang : ::GetUserDefaultLangID());    // In failure case, try our best! -} - - -inline HRESULT SpGetDescription(ISpObjectToken * pObjToken, WCHAR ** ppszDescription, LANGID Language = SpGetUserDefaultUILanguage()) -{ -    WCHAR szLangId[10]; -    SpHexFromUlong(szLangId, Language); -    HRESULT hr = pObjToken->GetStringValue(szLangId, ppszDescription); -    if (hr == SPERR_NOT_FOUND) -    { -        hr = pObjToken->GetStringValue(NULL, ppszDescription); -    } -    return hr; -} - - -inline HRESULT SpSetDescription(ISpObjectToken * pObjToken, const WCHAR * pszDescription, LANGID Language = SpGetUserDefaultUILanguage(), BOOL fSetLangIndependentId = TRUE) -{ -    WCHAR szLangId[10]; -    SpHexFromUlong(szLangId, Language); -    HRESULT hr = pObjToken->SetStringValue(szLangId, pszDescription); -    if (SUCCEEDED(hr) && fSetLangIndependentId) -    { -        hr = pObjToken->SetStringValue(NULL, pszDescription); -    } -    return hr; -} - -/**************************************************************************** -* SpConvertStreamFormatEnum * -*---------------------------* -*   Description: -*       This method converts the specified stream format into a wave format -*   structure. -* -*****************************************************************************/ -inline HRESULT SpConvertStreamFormatEnum(SPSTREAMFORMAT eFormat, GUID * pFormatId, WAVEFORMATEX ** ppCoMemWaveFormatEx) -{ -    HRESULT hr = S_OK; - -    if(pFormatId==NULL || ::IsBadWritePtr(pFormatId, sizeof(*pFormatId)) -        || ppCoMemWaveFormatEx==NULL || ::IsBadWritePtr(ppCoMemWaveFormatEx, sizeof(*ppCoMemWaveFormatEx))) -    { -        return E_INVALIDARG; -    } - -    const GUID * pFmtGuid = &GUID_NULL;     // Assume failure case -    if( eFormat >= SPSF_8kHz8BitMono && eFormat <= SPSF_48kHz16BitStereo ) -    { -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc(sizeof(WAVEFORMATEX)); -        *ppCoMemWaveFormatEx = pwfex; -        if (pwfex) -        { -            DWORD dwIndex = eFormat - SPSF_8kHz8BitMono; -            BOOL bIsStereo = dwIndex & 0x1; -            BOOL bIs16 = dwIndex & 0x2; -            DWORD dwKHZ = (dwIndex & 0x3c) >> 2; -            static const DWORD adwKHZ[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 }; -            pwfex->wFormatTag = WAVE_FORMAT_PCM; -            pwfex->nChannels = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1); -            pwfex->nSamplesPerSec = adwKHZ[dwKHZ]; -            pwfex->wBitsPerSample = 8; -            if (bIs16) -            { -                pwfex->wBitsPerSample *= 2; -                pwfex->nBlockAlign *= 2; -            } -                pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign; -            pwfex->cbSize = 0; -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else if( eFormat == SPSF_TrueSpeech_8kHz1BitMono ) -    { -        int NumBytes = sizeof( WAVEFORMATEX ) + 32; -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes ); -        *ppCoMemWaveFormatEx = pwfex; -        if( pwfex ) -        { -            memset( pwfex, 0, NumBytes ); -            pwfex->wFormatTag      = WAVE_FORMAT_DSPGROUP_TRUESPEECH; -            pwfex->nChannels       = 1; -            pwfex->nSamplesPerSec  = 8000; -            pwfex->nAvgBytesPerSec = 1067; -            pwfex->nBlockAlign     = 32; -            pwfex->wBitsPerSample  = 1; -            pwfex->cbSize          = 32; -            BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX ); -            pExtra[0] = 1; -            pExtra[2] = 0xF0; -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else if( (eFormat >= SPSF_CCITT_ALaw_8kHzMono    ) && -             (eFormat <= SPSF_CCITT_ALaw_44kHzStereo ) ) -    { -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( sizeof(WAVEFORMATEX) ); -        *ppCoMemWaveFormatEx = pwfex; -        if( pwfex ) -        { -            memset( pwfex, 0, sizeof(WAVEFORMATEX) ); -            DWORD dwIndex = eFormat - SPSF_CCITT_ALaw_8kHzMono; -            DWORD dwKHZ = dwIndex / 2; -            static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 }; -            BOOL bIsStereo    = dwIndex & 0x1; -            pwfex->wFormatTag = WAVE_FORMAT_ALAW; -            pwfex->nChannels  = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1); -            pwfex->nSamplesPerSec  = adwKHZ[dwKHZ]; -            pwfex->wBitsPerSample  = 8; -                pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign; -            pwfex->cbSize          = 0; -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else if( (eFormat >= SPSF_CCITT_uLaw_8kHzMono    ) && -             (eFormat <= SPSF_CCITT_uLaw_44kHzStereo ) ) -    { -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( sizeof(WAVEFORMATEX) ); -        *ppCoMemWaveFormatEx = pwfex; -        if( pwfex ) -        { -            memset( pwfex, 0, sizeof(WAVEFORMATEX) ); -            DWORD dwIndex = eFormat - SPSF_CCITT_uLaw_8kHzMono; -            DWORD dwKHZ = dwIndex / 2; -            static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 }; -            BOOL bIsStereo    = dwIndex & 0x1; -            pwfex->wFormatTag = WAVE_FORMAT_MULAW; -            pwfex->nChannels  = pwfex->nBlockAlign = (WORD)(bIsStereo ? 2 : 1); -            pwfex->nSamplesPerSec  = adwKHZ[dwKHZ]; -            pwfex->wBitsPerSample  = 8; -                pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nBlockAlign; -            pwfex->cbSize          = 0; -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else if( (eFormat >= SPSF_ADPCM_8kHzMono    ) && -             (eFormat <= SPSF_ADPCM_44kHzStereo ) ) -    { -        int NumBytes = sizeof( WAVEFORMATEX ) + 32; -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes ); -        *ppCoMemWaveFormatEx = pwfex; -        if( pwfex ) -        { -            //--- Some of these values seem odd. We used what the codec told us. -            static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 }; -            static const DWORD BytesPerSec[] = { 4096, 8192, 5644, 11289, 11155, 22311, 22179, 44359 }; -            static const DWORD BlockAlign[]  = { 256, 256, 512, 1024 }; -            static const BYTE Extra811[32] = -            { -                0xF4, 0x01, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, -                0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, -                0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00, -                0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF -            }; - -            static const BYTE Extra22[32] = -            { -                0xF4, 0x03, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, -                0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, -                0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00, -                0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF -            }; - -            static const BYTE Extra44[32] = -            { -                0xF4, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, -                0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, -                0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00, -                0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF -            }; - -            static const BYTE* Extra[4] = { Extra811, Extra811, Extra22, Extra44 }; -            memset( pwfex, 0, NumBytes ); -            DWORD dwIndex  = eFormat - SPSF_ADPCM_8kHzMono; -            DWORD dwKHZ    = dwIndex / 2; -            BOOL bIsStereo = dwIndex & 0x1; -            pwfex->wFormatTag      = WAVE_FORMAT_ADPCM; -            pwfex->nChannels       = (WORD)(bIsStereo ? 2 : 1); -            pwfex->nSamplesPerSec  = adwKHZ[dwKHZ]; -            pwfex->nAvgBytesPerSec = BytesPerSec[dwIndex]; -            pwfex->nBlockAlign     = (WORD)(BlockAlign[dwKHZ] * pwfex->nChannels); -            pwfex->wBitsPerSample  = 4; -            pwfex->cbSize          = 32; -            BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX ); -            memcpy( pExtra, Extra[dwKHZ], 32 ); -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else if( (eFormat >= SPSF_GSM610_8kHzMono    ) && -             (eFormat <= SPSF_GSM610_44kHzMono ) ) -    { -        int NumBytes = sizeof( WAVEFORMATEX ) + 2; -        WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes ); -        *ppCoMemWaveFormatEx = pwfex; -        if( pwfex ) -        { -            //--- Some of these values seem odd. We used what the codec told us. -            static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 }; -            static const DWORD BytesPerSec[] = { 1625, 2239, 4478, 8957 }; -            memset( pwfex, 0, NumBytes ); -            DWORD dwIndex          = eFormat - SPSF_GSM610_8kHzMono; -            pwfex->wFormatTag      = WAVE_FORMAT_GSM610; -            pwfex->nChannels       = 1; -            pwfex->nSamplesPerSec  = adwKHZ[dwIndex]; -            pwfex->nAvgBytesPerSec = BytesPerSec[dwIndex]; -            pwfex->nBlockAlign     = 65; -            pwfex->wBitsPerSample  = 0; -            pwfex->cbSize          = 2; -            BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX ); -            pExtra[0] = 0x40; -            pExtra[1] = 0x01; -            pFmtGuid = &SPDFID_WaveFormatEx; -        } -        else -        { -            hr = E_OUTOFMEMORY; -        } -    } -    else -    { -        *ppCoMemWaveFormatEx = NULL; -        switch (eFormat) -        { -        case SPSF_NoAssignedFormat: -            break; -        case SPSF_Text: -            pFmtGuid = &SPDFID_Text; -            break; -        default: -            hr = E_INVALIDARG; -            break; -        } -    } -    *pFormatId = *pFmtGuid; -    return hr; -} - -class CSpStreamFormat -{ -public: -    GUID            m_guidFormatId; -    WAVEFORMATEX  * m_pCoMemWaveFormatEx;  - - -    static HRESULT CoMemCopyWFEX(const WAVEFORMATEX * pSrc, WAVEFORMATEX ** ppCoMemWFEX) -    { -        ULONG cb = sizeof(WAVEFORMATEX) + pSrc->cbSize; -        *ppCoMemWFEX = (WAVEFORMATEX *)::CoTaskMemAlloc(cb); -        if (*ppCoMemWFEX) -        { -            memcpy(*ppCoMemWFEX, pSrc, cb); -            return S_OK; -        } -        else -        { -            return E_OUTOFMEMORY; -        } -    } - - -    CSpStreamFormat() -    { -        m_guidFormatId = GUID_NULL; -        m_pCoMemWaveFormatEx = NULL; -    } - -    CSpStreamFormat(SPSTREAMFORMAT eFormat, HRESULT * phr) -    { -        *phr = SpConvertStreamFormatEnum(eFormat, &m_guidFormatId, &m_pCoMemWaveFormatEx); -    } - -    CSpStreamFormat(const WAVEFORMATEX * pWaveFormatEx, HRESULT * phr) -    { -        *phr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx); -        m_guidFormatId = SUCCEEDED(*phr) ? SPDFID_WaveFormatEx : GUID_NULL; -    } - -    ~CSpStreamFormat() -    { -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -    } - -    void Clear() -    { -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -        m_pCoMemWaveFormatEx = NULL; -        memset(&m_guidFormatId, 0, sizeof(m_guidFormatId)); -    } - -    const GUID & FormatId() const  -    { -        return m_guidFormatId; -    } - -    const WAVEFORMATEX * WaveFormatExPtr() const -    { -        return m_pCoMemWaveFormatEx; -    } - - -    HRESULT AssignFormat(SPSTREAMFORMAT eFormat) -    { -        ::CoTaskMemFree(m_pCoMemWaveFormatEx);     -        return SpConvertStreamFormatEnum(eFormat, &m_guidFormatId, &m_pCoMemWaveFormatEx); -    } - -    HRESULT AssignFormat(ISpStreamFormat * pStream) -    { -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -        m_pCoMemWaveFormatEx = NULL; -        return pStream->GetFormat(&m_guidFormatId, &m_pCoMemWaveFormatEx); -    } - -    HRESULT AssignFormat(const WAVEFORMATEX * pWaveFormatEx) -    { -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -        HRESULT hr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx); -        m_guidFormatId = SUCCEEDED(hr) ? SPDFID_WaveFormatEx : GUID_NULL; -        return hr; -    } - -    HRESULT AssignFormat(REFGUID rguidFormatId, const WAVEFORMATEX * pWaveFormatEx) -    { -        HRESULT hr = S_OK; - -        m_guidFormatId = rguidFormatId; -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -        m_pCoMemWaveFormatEx = NULL; - -        if (rguidFormatId == SPDFID_WaveFormatEx) -        { -            if (::IsBadReadPtr(pWaveFormatEx, sizeof(*pWaveFormatEx))) -            { -                hr = E_INVALIDARG; -            } -            else  -            { -                hr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx); -            } - -            if (FAILED(hr)) -            { -                m_guidFormatId = GUID_NULL; -            } -        } - -        return hr; -    } - - -    BOOL IsEqual(REFGUID rguidFormatId, const WAVEFORMATEX * pwfex) const -    { -        if (rguidFormatId == m_guidFormatId) -        { -            if (m_pCoMemWaveFormatEx) -            { -                if (pwfex && -                    pwfex->cbSize == m_pCoMemWaveFormatEx->cbSize && -                    memcmp(m_pCoMemWaveFormatEx, pwfex, sizeof(WAVEFORMATEX) + pwfex->cbSize) == 0) -                { -                    return TRUE; -                } -            } -            else -            { -                return (pwfex == NULL); -            } -        } -        return FALSE; -    } - - - -    HRESULT ParamValidateAssignFormat(REFGUID rguidFormatId, const WAVEFORMATEX * pWaveFormatEx, BOOL fRequireWaveFormat = FALSE) -    { -        if ((pWaveFormatEx && (::IsBadReadPtr(pWaveFormatEx, sizeof(*pWaveFormatEx)) || rguidFormatId != SPDFID_WaveFormatEx)) || -            (fRequireWaveFormat && pWaveFormatEx == NULL)) -        { -            return E_INVALIDARG; -        } -        return AssignFormat(rguidFormatId, pWaveFormatEx); -    } - -    SPSTREAMFORMAT ComputeFormatEnum() -    { -        if (m_guidFormatId == GUID_NULL) -        { -            return SPSF_NoAssignedFormat; -        } -        if (m_guidFormatId == SPDFID_Text) -        { -            return SPSF_Text; -        } -        if (m_guidFormatId != SPDFID_WaveFormatEx) -        { -            return SPSF_NonStandardFormat; -        } -        // -        //  It is a WAVEFORMATEX.  Now determine which type it is and convert. -        // -        DWORD dwIndex = 0; -        switch (m_pCoMemWaveFormatEx->wFormatTag) -        { -          case WAVE_FORMAT_PCM: -          { -            switch (m_pCoMemWaveFormatEx->nChannels) -            { -              case 1: -                break; -              case 2: -                dwIndex |= 1; -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            switch (m_pCoMemWaveFormatEx->wBitsPerSample) -            { -              case 8: -                break; -              case 16: -                dwIndex |= 2; -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            switch (m_pCoMemWaveFormatEx->nSamplesPerSec) -            { -              case 48000: -                dwIndex += 4;   // Fall through -              case 44100: -                dwIndex += 4;   // Fall through -              case 32000: -                dwIndex += 4;   // Fall through -              case 24000: -                dwIndex += 4;   // Fall through -              case 22050: -                dwIndex += 4;   // Fall through -              case 16000: -                dwIndex += 4;   // Fall through -              case 12000: -                dwIndex += 4;   // Fall through -              case 11025: -                dwIndex += 4;   // Fall through -              case 8000: -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            return static_cast<SPSTREAMFORMAT>(SPSF_8kHz8BitMono + dwIndex); -          } - -          case WAVE_FORMAT_DSPGROUP_TRUESPEECH: -          { -            return SPSF_TrueSpeech_8kHz1BitMono; -          } - -          case WAVE_FORMAT_ALAW: // fall through -          case WAVE_FORMAT_MULAW: -          case WAVE_FORMAT_ADPCM: -          { -            switch (m_pCoMemWaveFormatEx->nChannels) -            { -              case 1: -                break; -              case 2: -                dwIndex |= 1; -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            if(m_pCoMemWaveFormatEx->wFormatTag == WAVE_FORMAT_ADPCM) -            { -                if(m_pCoMemWaveFormatEx->wBitsPerSample != 4) -                { -                    return SPSF_ExtendedAudioFormat; -                } -            } -            else if(m_pCoMemWaveFormatEx->wBitsPerSample != 8) -            { -                return SPSF_ExtendedAudioFormat; -            } - -            switch (m_pCoMemWaveFormatEx->nSamplesPerSec) -            { -              case 44100: -                dwIndex += 2;   // Fall through -              case 22050: -                dwIndex += 2;   // Fall through -              case 11025: -                dwIndex += 2;   // Fall through -              case 8000: -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            switch( m_pCoMemWaveFormatEx->wFormatTag ) -            { -              case WAVE_FORMAT_ALAW: -                return static_cast<SPSTREAMFORMAT>(SPSF_CCITT_ALaw_8kHzMono + dwIndex); -              case WAVE_FORMAT_MULAW: -                return static_cast<SPSTREAMFORMAT>(SPSF_CCITT_uLaw_8kHzMono + dwIndex); -              case WAVE_FORMAT_ADPCM: -                return static_cast<SPSTREAMFORMAT>(SPSF_ADPCM_8kHzMono + dwIndex); -            } -          } - -          case WAVE_FORMAT_GSM610: -          { -            if( m_pCoMemWaveFormatEx->nChannels != 1 ) -            { -                return SPSF_ExtendedAudioFormat; -            } - -            switch (m_pCoMemWaveFormatEx->nSamplesPerSec) -            { -              case 44100: -                dwIndex = 3; -                break; -              case 22050: -                dwIndex = 2; -                break; -              case 11025: -                dwIndex = 1; -                break; -              case 8000: -                dwIndex = 0; -                break; -              default: -                return SPSF_ExtendedAudioFormat; -            } - -            return static_cast<SPSTREAMFORMAT>(SPSF_GSM610_8kHzMono + dwIndex); -          } - -          default: -            return SPSF_ExtendedAudioFormat; -            break; -        } -    } - -    void DetachTo(CSpStreamFormat & Other) -    { -        ::CoTaskMemFree(Other.m_pCoMemWaveFormatEx); -        Other.m_guidFormatId = m_guidFormatId; -        Other.m_pCoMemWaveFormatEx = m_pCoMemWaveFormatEx; -        m_pCoMemWaveFormatEx = NULL; -        memset(&m_guidFormatId, 0, sizeof(m_guidFormatId)); -    } - -    void DetachTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWaveFormatEx) -    { -        *pFormatId = m_guidFormatId; -        *ppCoMemWaveFormatEx = m_pCoMemWaveFormatEx; -        m_pCoMemWaveFormatEx = NULL; -        memset(&m_guidFormatId, 0, sizeof(m_guidFormatId)); -    } - -    HRESULT CopyTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWFEX) const -    { -        HRESULT hr = S_OK; -        *pFormatId = m_guidFormatId; -        if (m_pCoMemWaveFormatEx) -        { -            hr = CoMemCopyWFEX(m_pCoMemWaveFormatEx, ppCoMemWFEX); -            if (FAILED(hr)) -            { -                memset(pFormatId, 0, sizeof(*pFormatId)); -            } -        } -        else -        { -            *ppCoMemWFEX = NULL; -        } -        return hr; -    } - -    HRESULT CopyTo(CSpStreamFormat & Other) const -    { -        ::CoTaskMemFree(Other.m_pCoMemWaveFormatEx); -        return CopyTo(&Other.m_guidFormatId, &Other.m_pCoMemWaveFormatEx); -    } -     -    HRESULT AssignFormat(const CSpStreamFormat & Src) -    { -        return Src.CopyTo(*this); -    } - - -    HRESULT ParamValidateCopyTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWFEX) const -    { -        if (::IsBadWritePtr(pFormatId, sizeof(*pFormatId)) || -            ::IsBadWritePtr(ppCoMemWFEX, sizeof(*ppCoMemWFEX))) -        { -            return E_POINTER; -        } -        return CopyTo(pFormatId, ppCoMemWFEX); -    } - -    BOOL operator==(const CSpStreamFormat & Other) const -    { -        return IsEqual(Other.m_guidFormatId, Other.m_pCoMemWaveFormatEx); -    } -    BOOL operator!=(const CSpStreamFormat & Other) const -    { -        return !IsEqual(Other.m_guidFormatId, Other.m_pCoMemWaveFormatEx); -    } - -    ULONG SerializeSize() const -    { -        ULONG cb = sizeof(ULONG) + sizeof(m_guidFormatId); -        if (m_pCoMemWaveFormatEx) -        { -            cb += sizeof(WAVEFORMATEX) + m_pCoMemWaveFormatEx->cbSize + 3;  // Add 3 to round up -            cb -= cb % 4;                                                   // Round to DWORD -        } -        return cb; -    } - -    ULONG Serialize(BYTE * pBuffer) const -    { -        ULONG cb = SerializeSize(); -        *((UNALIGNED ULONG *)pBuffer) = cb; -        pBuffer += sizeof(ULONG); -        *((UNALIGNED GUID *)pBuffer) = m_guidFormatId; -        if (m_pCoMemWaveFormatEx) -        { -            pBuffer += sizeof(m_guidFormatId); -            memcpy(pBuffer, m_pCoMemWaveFormatEx, sizeof(WAVEFORMATEX) + m_pCoMemWaveFormatEx->cbSize); -        } -        return cb; -    } - -    HRESULT Deserialize(const BYTE * pBuffer, ULONG * pcbUsed) -    { -        HRESULT hr = S_OK; -        ::CoTaskMemFree(m_pCoMemWaveFormatEx); -        m_pCoMemWaveFormatEx = NULL; -        *pcbUsed = *((UNALIGNED ULONG *)pBuffer); -        pBuffer += sizeof(ULONG); -        // Misaligment exception is generated for SHx platform. -        // Marking pointer as UNALIGNED does not help. -#ifndef _WIN32_WCE -        m_guidFormatId = *((UNALIGNED GUID *)pBuffer); -#else -        memcpy(&m_guidFormatId, pBuffer, sizeof(GUID)); -#endif -        if (*pcbUsed > sizeof(GUID) + sizeof(ULONG)) -        { -            pBuffer += sizeof(m_guidFormatId); -            hr = CoMemCopyWFEX((const WAVEFORMATEX *)pBuffer, &m_pCoMemWaveFormatEx); -            if (FAILED(hr)) -            { -                m_guidFormatId = GUID_NULL; -            } -        } -        return hr; -    } - -}; - - - -// Return the default codepage given a LCID. -// Note some of the newer locales do not have associated Windows codepages.  For these, we return UTF-8. - -inline UINT SpCodePageFromLcid(LCID lcid) -{ -    char achCodePage[6]; - -    return (0 != GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, achCodePage, sizeof(achCodePage))) ? atoi(achCodePage) : 65001; -} - - -/**************************************************************************** -* SpClearEvent * -*--------------* -*   Description: -*       Helper function that can be used by clients that do not use the CSpEvent -*   class. -* -*   Returns: -* -*****************************************************************************/ - -inline void SpClearEvent(SPEVENT * pe) -{ -    if( pe->elParamType != SPEI_UNDEFINED) -    { -        if( pe->elParamType == SPET_LPARAM_IS_POINTER || -            pe->elParamType == SPET_LPARAM_IS_STRING) -        { -            ::CoTaskMemFree((void *)pe->lParam); -        } -        else if (pe->elParamType == SPET_LPARAM_IS_TOKEN || -               pe->elParamType == SPET_LPARAM_IS_OBJECT) -        { -            ((IUnknown*)pe->lParam)->Release(); -        } -    } -    memset(pe, 0, sizeof(*pe)); -} - -/**************************************************************************** -* SpInitEvent * -*-------------* -*   Description: -* -*   Returns: -* -*****************************************************************************/ - -inline void SpInitEvent(SPEVENT * pe) -{ -    memset(pe, 0, sizeof(*pe)); -} - -/**************************************************************************** -* SpEventSerializeSize * -*----------------------* -*   Description: -*       Computes the required size of a buffer to serialize an event.  The caller -*   must specify which type of serialized event is desired -- either SPSERIALIZEDEVENT -*   or SPSERIALIZEDEVENT64.     -* -*   Returns: -*       Size in bytes required to seriailze the event. -* -****************************************************************************/ - -// WCE compiler does not work propertly with template -#ifndef _WIN32_WCE -template <class T> -inline ULONG SpEventSerializeSize(const SPEVENT * pEvent) - -{ -    ULONG ulSize = sizeof(T); - -#else - -inline ULONG SpEventSerializeSize(const SPEVENT * pEvent, ULONG ulSize) -{ -#endif //_WIN32_WCE - -    if( ( pEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pEvent->lParam ) -    { -        ulSize += ULONG(pEvent->wParam); -    } -    else if ((pEvent->elParamType == SPET_LPARAM_IS_STRING) && pEvent->lParam != NULL) -    { -        ulSize += (wcslen((WCHAR*)pEvent->lParam) + 1) * sizeof( WCHAR ); -    } -    else if( pEvent->elParamType == SPET_LPARAM_IS_TOKEN ) -    { -        CSpDynamicString dstrObjectId; -        if( ((ISpObjectToken*)(pEvent->lParam))->GetId( &dstrObjectId ) == S_OK ) -        { -            ulSize += (dstrObjectId.Length() + 1) * sizeof( WCHAR ); -        } -    } -    // Round up to nearest DWORD -    ulSize += 3; -    ulSize -= ulSize % 4; -    return ulSize; -} - -/**************************************************************************** -* SpSerializedEventSize * -*-----------------------* -*   Description: -*       Returns the size, in bytes, used by a serialized event.  The caller can -*   pass a pointer to either a SPSERIAILZEDEVENT or SPSERIALIZEDEVENT64 structure. -* -*   Returns: -*       Number of bytes used by serizlied event -* -********************************************************************* RAL ***/ - -// WCE compiler does not work propertly with template -#ifndef _WIN32_WCE -template <class T> -inline ULONG SpSerializedEventSize(const T * pSerEvent) -{ -    ULONG ulSize = sizeof(T); - -    if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam ) -    { -        ulSize += ULONG(pSerEvent->SerializedwParam); -    } -    else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) && -             pSerEvent->SerializedlParam != NULL) -    { -        ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR ); -    } -    // Round up to nearest DWORD -    ulSize += 3; -    ulSize -= ulSize % 4; -    return ulSize; -} - -#else //_WIN32_WCE - -inline ULONG SpSerializedEventSize(const SPSERIALIZEDEVENT * pSerEvent, ULONG ulSize) -{ -    if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam ) -    { -        ulSize += ULONG(pSerEvent->SerializedwParam); -    } -    else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) && -             pSerEvent->SerializedlParam != NULL) -    { -        ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR ); -    } -    // Round up to nearest DWORD -    ulSize += 3; -    ulSize -= ulSize % 4; -    return ulSize; -} - -inline ULONG SpSerializedEventSize(const SPSERIALIZEDEVENT64 * pSerEvent, ULONG ulSize) -{ -    if( ( pSerEvent->elParamType == SPET_LPARAM_IS_POINTER ) && pSerEvent->SerializedlParam ) -    { -        ulSize += ULONG(pSerEvent->SerializedwParam); -    } -    else if ((pSerEvent->elParamType == SPET_LPARAM_IS_STRING || pSerEvent->elParamType == SPET_LPARAM_IS_TOKEN) && -             pSerEvent->SerializedlParam != NULL) -    { -        ulSize += (wcslen((WCHAR*)(pSerEvent + 1)) + 1) * sizeof( WCHAR ); -    } -    // Round up to nearest DWORD -    ulSize += 3; -    ulSize -= ulSize % 4; -    return ulSize; -} - -#endif //_WIN32_WCE - -/*** CSpEvent helper class -* -*/ -class CSpEvent : public SPEVENT -{ -public: -    CSpEvent() -    { -        SpInitEvent(this); -    } -    ~CSpEvent() -    { -        SpClearEvent(this); -    } -    // If you need to take the address of a CSpEvent that is not const, use the AddrOf() method -    // which will do debug checking of parameters.  If you encounter this problem when calling -    // GetEvents from an event source, you may want to use the GetFrom() method of this class. -    const SPEVENT * operator&() -        { -                return this; -        } -    CSpEvent * AddrOf() -    { -        // Note:  This method does not ASSERT since we assume the caller knows what they are doing. -        return this; -    } -    void Clear() -    { -        SpClearEvent(this); -    } -    HRESULT CopyTo(SPEVENT * pDestEvent) const -    { -        memcpy(pDestEvent, this, sizeof(*pDestEvent)); -        if ((elParamType == SPET_LPARAM_IS_POINTER) && lParam) -        { -            pDestEvent->lParam = (LPARAM)::CoTaskMemAlloc(wParam); -            if (pDestEvent->lParam) -            { -                memcpy((void *)pDestEvent->lParam, (void *)lParam, wParam); -            } -            else -            { -                pDestEvent->eEventId = SPEI_UNDEFINED; -                return E_OUTOFMEMORY; -            } -        } -        else if (elParamType == SPET_LPARAM_IS_STRING && lParam != NULL) -        { -            pDestEvent->lParam = (LPARAM)::CoTaskMemAlloc((wcslen((WCHAR*)lParam) + 1) * sizeof(WCHAR)); -            if (pDestEvent->lParam) -            { -                wcscpy((WCHAR*)pDestEvent->lParam, (WCHAR*)lParam); -            } -            else -            { -                pDestEvent->eEventId = SPEI_UNDEFINED; -                return E_OUTOFMEMORY; -            } -        } -        else if (elParamType == SPET_LPARAM_IS_TOKEN || -               elParamType == SPET_LPARAM_IS_OBJECT) -        { -            ((IUnknown*)lParam)->AddRef(); -        } -        return S_OK; -    } - -    HRESULT GetFrom(ISpEventSource * pEventSrc) -    { -        SpClearEvent(this); -        return pEventSrc->GetEvents(1, this, NULL); -    } -    HRESULT CopyFrom(const SPEVENT * pSrcEvent) -    { -        SpClearEvent(this); -        return static_cast<const CSpEvent *>(pSrcEvent)->CopyTo(this); -    } -    void Detach(SPEVENT * pDestEvent = NULL) -    { -        if (pDestEvent) -        { -            memcpy(pDestEvent, this, sizeof(*pDestEvent)); -        } -        memset(this, 0, sizeof(*this)); -    } - -    template <class T> -    ULONG SerializeSize() const -    { -        return SpEventSerializeSize<T>(this); -    } - -    // Call this method with either SPSERIALIZEDEVENT or SPSERIALIZEDEVENT64 -    template <class T> -    void Serialize(T * pSerEvent) const -    { -        pSerEvent->eEventId = this->eEventId; -        pSerEvent->elParamType = this->elParamType; -        pSerEvent->ulStreamNum = this->ulStreamNum; -        pSerEvent->ullAudioStreamOffset = this->ullAudioStreamOffset; -        pSerEvent->SerializedwParam = static_cast<ULONG>(this->wParam); -        pSerEvent->SerializedlParam = static_cast<LONG>(this->lParam); -        if (lParam) -        { -            switch(elParamType) -            { -            case SPET_LPARAM_IS_POINTER: -                memcpy(pSerEvent + 1, (void *)lParam, wParam); -                pSerEvent->SerializedlParam = sizeof(T); -                break; - -            case SPET_LPARAM_IS_STRING: -                wcscpy((WCHAR *)(pSerEvent + 1), (WCHAR*)lParam); -                pSerEvent->SerializedlParam = sizeof(T); -                break; - -            case SPET_LPARAM_IS_TOKEN: -                { -                    CSpDynamicString dstrObjectId; -                    if( SUCCEEDED( ((ISpObjectToken*)lParam)->GetId( &dstrObjectId ) ) ) -                    { -                        pSerEvent->SerializedwParam = (dstrObjectId.Length() + 1) * sizeof( WCHAR );; -                        memcpy( pSerEvent + 1, (void *)dstrObjectId.m_psz, static_cast<ULONG>(pSerEvent->SerializedwParam) ); -                    } -                    pSerEvent->SerializedlParam = sizeof(T); -                } -                break; - -            default: -                break; -            } -        } -    } - -    template <class T> -    HRESULT Serialize(T ** ppCoMemSerEvent, ULONG * pcbSerEvent) const  -    { -// WCE compiler does not work propertly with template -#ifndef _WIN32_WCE -        *pcbSerEvent = SpEventSerializeSize<T>(this); -#else -        *pcbSerEvent = SpEventSerializeSize(this, sizeof(** ppCoMemSerEvent)); -#endif -        *ppCoMemSerEvent = (T *)::CoTaskMemAlloc(*pcbSerEvent); -        if (*ppCoMemSerEvent) -        { -            Serialize(*ppCoMemSerEvent); -            return S_OK; -        } -        else -        { -            *pcbSerEvent = 0; -            return E_OUTOFMEMORY; -        } -    } - - -    // Call this method with either SPSERIALIZEDEVENT or SPSERIALIZEDEVENT64 -    template <class T> -    HRESULT Deserialize(const T * pSerEvent, ULONG * pcbUsed = NULL) -    { -        Clear(); -        HRESULT hr = S_OK; -        const UNALIGNED T * pTemp = pSerEvent; -        this->eEventId = pTemp->eEventId; -        this->elParamType = pTemp->elParamType; -        this->ulStreamNum = pTemp->ulStreamNum; -        this->ullAudioStreamOffset = pTemp->ullAudioStreamOffset; -        this->wParam = static_cast<WPARAM>(pTemp->SerializedwParam); -        this->lParam = static_cast<LPARAM>(pTemp->SerializedlParam); -        if (pTemp->SerializedlParam) -        { -            ULONG cbAlloc = 0; -            switch (pTemp->elParamType) -            { -            case SPET_LPARAM_IS_POINTER: -                cbAlloc = static_cast<ULONG>(wParam); -                break; - -            case SPET_LPARAM_IS_STRING: -                cbAlloc = sizeof(WCHAR) * (1 + wcslen((const WCHAR *)(pTemp + 1))); -                break; - -            case SPET_LPARAM_IS_TOKEN: -                { -                    ULONG ulDataOffset = ULONG(lParam); -                    hr = SpGetTokenFromId( (const WCHAR*)(pTemp + 1), -                                                  (ISpObjectToken **)&lParam ); -                    wParam = 0; -                } -                break; -            } -            if (cbAlloc) -            { -                void * pvBuff = ::CoTaskMemAlloc(cbAlloc); -                this->lParam = (LPARAM)pvBuff; -                if (pvBuff) -                { -                    memcpy(pvBuff, pTemp + 1, cbAlloc); -                } -                else -                { -                    hr = E_OUTOFMEMORY; -                } -            } -        } - -        if( SUCCEEDED( hr ) && pcbUsed ) -        { -// WCE compiler does not work propertly with template -#ifndef _WIN32_WCE -            *pcbUsed = SpEventSerializeSize<T>(this); -#else -            *pcbUsed = SpEventSerializeSize(this, sizeof(*pTemp)); -#endif -        } -        return hr; -    } - -    // -    //  Helpers for access to events.  Performs run-time checks in debug and casts -    //  data to the appropriate types -    // -    SPPHONEID Phoneme() const  -    { -        return (SPPHONEID)LOWORD(lParam); -    } -    SPVISEMES Viseme() const  -    { -        return (SPVISEMES)LOWORD(lParam); -    } -    ULONG InputWordPos() const -    { -        return ULONG(lParam); -    } -    ULONG InputWordLen() const  -    { -        return ULONG(wParam); -    } -    ULONG InputSentPos() const -    { -        return ULONG(lParam); -    } -    ULONG InputSentLen() const  -    { -        return ULONG(wParam); -    } -    ISpObjectToken * ObjectToken() const -    { -        return (ISpObjectToken *)lParam; -    } -    ISpObjectToken * VoiceToken() const     // More explicit check than ObjectToken() -    { -        return ObjectToken(); -    } -    BOOL PersistVoiceChange() const -    { -        return (BOOL)wParam; -    } -    IUnknown * Object() const -    { -        return (IUnknown*)lParam; -    } -    ISpRecoResult * RecoResult() const -    { -        return (ISpRecoResult *)Object(); -    } -    BOOL IsPaused() -    { -        return (BOOL)(wParam & SPREF_AutoPause); -    } -    BOOL IsEmulated() -    { -        return (BOOL)(wParam & SPREF_Emulated); -    } -    const WCHAR * String() const -    { -        return (const WCHAR*)lParam; -    } -    const WCHAR * BookmarkName() const -    { -        return String(); -    } -    const WCHAR * RequestTypeOfUI() const -    { -        return String(); -    } -    SPRECOSTATE RecoState() const -    { -        return static_cast<SPRECOSTATE>(wParam); -    } -    const WCHAR * PropertyName() const -    { -        // Note: Don't use String() method here since in the case of string attributes, the elParamType -        // field specifies LPARAM_IS_POINTER, but the attribute name IS the first string in this buffer -        return (const WCHAR*)lParam; -    } -    const LONG PropertyNumValue() const  -    { -        return static_cast<LONG>(wParam); -    } -    const WCHAR * PropertyStringValue() const -    { -        // Search for the first NULL and return pointer to the char past it. -	const WCHAR *psz; -        for (psz = (const WCHAR *)lParam; *psz; psz++) {} -        return psz + 1; -    } -    SPINTERFERENCE Interference() const -    { -        return static_cast<SPINTERFERENCE>(lParam); -    } -    HRESULT EndStreamResult() const -    { -        return static_cast<HRESULT>(lParam); -    } -    BOOL InputStreamReleased() const -    { -        return (wParam & SPESF_STREAM_RELEASED) ? TRUE : FALSE; -    } -}; - -class CSpPhrasePtr -{ -public: -    SPPHRASE    *   m_pPhrase; -    CSpPhrasePtr() : m_pPhrase(NULL) {} -    CSpPhrasePtr(ISpPhrase * pPhraseObj, HRESULT * phr) -    { -        *phr = pPhraseObj->GetPhrase(&m_pPhrase); -    } -    ~CSpPhrasePtr() -    { -        ::CoTaskMemFree(m_pPhrase); -    } -        //The assert on operator& usually indicates a bug.  If this is really -        //what is needed, however, take the address of the m_pPhrase member explicitly. -        SPPHRASE ** operator&() -        { -            return &m_pPhrase; -        } -    operator SPPHRASE *() const -    { -        return m_pPhrase; -    } -        SPPHRASE & operator*() const -        { -                return *m_pPhrase; -        } -    SPPHRASE * operator->() const -    { -        return m_pPhrase; -    } -        bool operator!() const -        { -                return (m_pPhrase == NULL); -        } -    void Clear() -    { -        if (m_pPhrase) -        { -            ::CoTaskMemFree(m_pPhrase); -            m_pPhrase = NULL; -        } -    } -    HRESULT GetFrom(ISpPhrase * pPhraseObj) -    { -        Clear(); -        return pPhraseObj->GetPhrase(&m_pPhrase); -    } -}; - - -template <class T> -class CSpCoTaskMemPtr -{ -public: -    T       * m_pT; -    CSpCoTaskMemPtr() : m_pT(NULL) {} -    CSpCoTaskMemPtr(void * pv) : m_pT((T *)pv) {} -    CSpCoTaskMemPtr(ULONG cElements, HRESULT * phr) -    { -        m_pT = (T *)::CoTaskMemAlloc(cElements * sizeof(T)); -        *phr = m_pT ? S_OK : E_OUTOFMEMORY; -    } -    ~CSpCoTaskMemPtr() -    { -        ::CoTaskMemFree(m_pT); -    } -    void Clear() -    { -        if (m_pT) -        { -            ::CoTaskMemFree(m_pT); -            m_pT = NULL; -        } -    } -    HRESULT Alloc(ULONG cArrayElements = 1) -    { -        m_pT = (T *)::CoTaskMemRealloc(m_pT, sizeof(T) * cArrayElements); -        return (m_pT ? S_OK : E_OUTOFMEMORY); -    } -    void Attach(void * pv) -    { -        Clear(); -        m_pT = (T *)pv; -    } -    T * Detatch() -    { -        T * pT = m_pT; -        m_pT = NULL; -        return pT; -    } -        //The assert on operator& usually indicates a bug.  If this is really -        //what is needed, however, take the address of the m_pT member explicitly. -        T ** operator&() -        { -                return &m_pT; -        } -    T * operator->() -    { -        return m_pT; -    } -    operator T *() -    { -        return m_pT; -    } -        bool operator!() const -        { -                return (m_pT == NULL); -        } -}; - - -#endif /* This must be the last line in the file */ diff --git a/backends/text-to-speech/windows/windows-text-to-speech.cpp b/backends/text-to-speech/windows/windows-text-to-speech.cpp index 2b405f5553..9f4ecf742a 100644 --- a/backends/text-to-speech/windows/windows-text-to-speech.cpp +++ b/backends/text-to-speech/windows/windows-text-to-speech.cpp @@ -30,18 +30,7 @@  #include <windows.h>  #include <servprov.h> -// Mingw-w64 is missing symbols for two guids declared in sapi.h which are used -//  by sphelper-scummvm.h. Mingw32 doesn't include any sapi headers or libraries -//  so the only way to currently build there is to manually use Microsoft's, in -//  which case the guids will be defined by their library. -#if defined(__MINGW32__) && defined(__MINGW64_VERSION_MAJOR) -#include <initguid.h> -DEFINE_GUID(SPDFID_Text, 0x7ceef9f9, 0x3d13, 0x11d2, 0x9e, 0xe7, 0x00, 0xc0, 0x4f, 0x79, 0x73, 0x96); -DEFINE_GUID(SPDFID_WaveFormatEx, 0xc31adbae, 0x527f, 0x4ff5, 0xa2, 0x30, 0xf6, 0x2b, 0xb6, 0x1f, 0xf7, 0x0c); -#endif -  #include <sapi.h> -#include "backends/text-to-speech/windows/sphelper-scummvm.h"  #include "backends/platform/sdl/win32/win32_wrapper.h"  #include "backends/text-to-speech/windows/windows-text-to-speech.h" @@ -78,16 +67,30 @@ void WindowsTextToSpeechManager::init() {  		return;  	// init audio -	CSpStreamFormat format; -	format.AssignFormat(SPSF_11kHz8BitMono); -	ISpObjectToken *pToken; -	HRESULT hr = SpGetDefaultTokenFromCategoryId(SPCAT_AUDIOOUT, &pToken); +	ISpObjectTokenCategory *pTokenCategory; +	HRESULT hr = CoCreateInstance(CLSID_SpObjectTokenCategory, NULL, CLSCTX_ALL, IID_ISpObjectTokenCategory, (void **)&pTokenCategory); +	if (SUCCEEDED(hr)) { +		hr = pTokenCategory->SetId(SPCAT_AUDIOOUT, TRUE); +		if (SUCCEEDED(hr)) { +			WCHAR *tokenId; +			hr = pTokenCategory->GetDefaultTokenId(&tokenId); +			if (SUCCEEDED(hr)) { +				ISpObjectToken *pToken; +				hr = CoCreateInstance(CLSID_SpObjectToken, NULL, CLSCTX_ALL, IID_ISpObjectToken, (void **)&pToken); +				if (SUCCEEDED(hr)) { +					hr = pToken->SetId(NULL, tokenId, FALSE); +					if (SUCCEEDED(hr)) { +						hr = pToken->CreateInstance(NULL, CLSCTX_ALL, IID_ISpAudio, (void **)&_audio); +					} +				} +				CoTaskMemFree(tokenId); +			} +		} +	}  	if (FAILED(hr)) {  		warning("Could not initialize TTS audio");  		return;  	} -	pToken->CreateInstance(NULL, CLSCTX_ALL, IID_ISpAudio, (void **)&_audio); -	_audio->SetFormat(format.FormatId(), format.WaveFormatExPtr());  	// init voice  	hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&_voice); @@ -348,18 +351,22 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {  	// description  	WCHAR *descW; -	SpGetDescription(voiceToken, &descW); -	char *buffer = Win32::unicodeToAnsi(descW); -	Common::String desc = buffer; +	char *buffer; +	Common::String desc; +	HRESULT hr = voiceToken->GetStringValue(NULL, &descW); +	if (SUCCEEDED(hr)) { +		buffer = Win32::unicodeToAnsi(descW); +		desc = buffer; +		delete[] buffer; +		CoTaskMemFree(descW); +	} +  	if (desc == "Sample TTS Voice") {  		// This is really bad voice, it is basicaly unusable -		free(buffer);  		return;  	} -	free(buffer);  	// voice attributes -	HRESULT hr = S_OK;  	ISpDataKey *key = nullptr;  	hr = voiceToken->OpenKey(L"Attributes", &key); @@ -379,7 +386,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {  	}  	buffer = Win32::unicodeToAnsi(data);  	Common::String language = lcidToLocale(buffer); -	free(buffer); +	delete[] buffer;  	CoTaskMemFree(data);  	// only get the voices for the current language @@ -397,7 +404,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {  	}  	buffer = Win32::unicodeToAnsi(data);  	Common::TTSVoice::Gender gender = !strcmp(buffer, "Male") ? Common::TTSVoice::MALE : Common::TTSVoice::FEMALE; -	free(buffer); +	delete[] buffer;  	CoTaskMemFree(data);  	// age @@ -409,7 +416,7 @@ void WindowsTextToSpeechManager::createVoice(void *cpVoiceToken) {  	}  	buffer = Win32::unicodeToAnsi(data);  	Common::TTSVoice::Age age = !strcmp(buffer, "Adult") ? Common::TTSVoice::ADULT : Common::TTSVoice::UNKNOWN_AGE; -	free(buffer); +	delete[] buffer;  	CoTaskMemFree(data);  	_ttsState->_availableVoices.push_back(Common::TTSVoice(gender, age, (void *) voiceToken, desc)); @@ -441,12 +448,19 @@ Common::String WindowsTextToSpeechManager::lcidToLocale(Common::String lcid) {  void WindowsTextToSpeechManager::updateVoices() {  	_ttsState->_availableVoices.clear(); -	HRESULT hr = S_OK;  	ISpObjectToken *cpVoiceToken = nullptr;  	IEnumSpObjectTokens *cpEnum = nullptr;  	unsigned long ulCount = 0; -	hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum); +	ISpObjectTokenCategory *cpCategory; +	HRESULT hr = CoCreateInstance(CLSID_SpObjectTokenCategory, NULL, CLSCTX_ALL, IID_ISpObjectTokenCategory, (void**)&cpCategory); +	if (SUCCEEDED(hr)) { +		hr = cpCategory->SetId(SPCAT_VOICES, FALSE); +		if (SUCCEEDED(hr)) { +			hr = cpCategory->EnumTokens(NULL, NULL, &cpEnum); +		} +	} +  	if (SUCCEEDED(hr)) {  		hr = cpEnum->GetCount(&ulCount);  	}  | 
