⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sphelper.h

📁 TTS语音开发示例
💻 H
📖 第 1 页 / 共 5 页
字号:
            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;
}


inline HRESULT SPBindToFile( LPCWSTR pFileName, SPFILEMODE eMode, ISpStream ** ppStream,
                            const GUID * pFormatId = NULL, const WAVEFORMATEX * pWaveFormatEx = NULL,
                            ULONGLONG ullEventInterest = SPFEI_ALL_EVENTS)
{
    HRESULT hr = ::CoCreateInstance(CLSID_SpStream, NULL, CLSCTX_ALL, __uuidof(*ppStream), (void **)ppStream);
    if (SUCCEEDED(hr))
    {
        hr = (*ppStream)->BindToFile(pFileName, eMode, pFormatId, pWaveFormatEx, ullEventInterest);
        if (FAILED(hr))
        {
            (*ppStream)->Release();
            *ppStream = NULL;
        }
    }
    return hr;
} /* SPBindToFile */

#ifndef _UNICODE
inline HRESULT SPBindToFile( const TCHAR * pFileName, SPFILEMODE eMode, ISpStream** ppStream, 
                             const GUID * pFormatId = NULL, const WAVEFORMATEX * pWaveFormatEx = NULL,
                             ULONGLONG ullEventInterest = SPFEI_ALL_EVENTS)
{
    WCHAR szWcharFileName[MAX_PATH];
    ::MultiByteToWideChar(CP_ACP, 0, pFileName, -1, szWcharFileName, sp_countof(szWcharFileName));
    return SPBindToFile(szWcharFileName, eMode, ppStream, pFormatId, pWaveFormatEx, ullEventInterest);
}
#endif

/****************************************************************************
* 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)
        {
            SPDBG_ASSERT(wParam && (wParam < 0x100000));    // this is too big!
            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
    {
        SPDBG_ASSERT(elParamType != SPET_LPARAM_IS_OBJECT);
        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->wP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -