Visual c++ C++;Microsoft SAPI:如何将Windows文本到语音输出设置为内存缓冲区?

Visual c++ C++;Microsoft SAPI:如何将Windows文本到语音输出设置为内存缓冲区?,visual-c++,text-to-speech,sapi,Visual C++,Text To Speech,Sapi,我一直在试图找出如何使用WindowsSAPI5.1将文本“说”到内存缓冲区中,但迄今为止没有成功,尽管看起来应该很简单 目前还没有将合成语音流式传输到.wav文件的方法,但没有将其流式传输到内存缓冲区的示例 最后,我需要在一个char*数组中以16 kHz 16位little endian PCM格式合成语音。目前我创建了一个temp.wav文件,将语音输出重定向到那里,然后读取它,但这似乎是一个相当愚蠢的解决方案 有人知道怎么做吗 谢谢 您知道如何创建内存映射文件吗?您可以查看ISpStre

我一直在试图找出如何使用WindowsSAPI5.1将文本“说”到内存缓冲区中,但迄今为止没有成功,尽管看起来应该很简单

目前还没有将合成语音流式传输到.wav文件的方法,但没有将其流式传输到内存缓冲区的示例

最后,我需要在一个char*数组中以16 kHz 16位little endian PCM格式合成语音。目前我创建了一个temp.wav文件,将语音输出重定向到那里,然后读取它,但这似乎是一个相当愚蠢的解决方案

有人知道怎么做吗


谢谢

您知道如何创建内存映射文件吗?您可以查看ISpStream是否将绑定到它。

查看ISpStream::SetBaseStream。这里有一个小助手:

inline HRESULT SPCreateStreamOnHGlobal(
                    HGLOBAL hGlobal,            //Memory handle for the stream object
                    BOOL fDeleteOnRelease,      //Whether to free memory when the object is released
                    const WAVEFORMATEX * pwfex, //WaveFormatEx for stream
                    ISpStream ** ppStream)      //Address of variable to receive ISpStream pointer
{
    HRESULT hr;
    IStream * pMemStream;
    *ppStream = NULL;
    hr = ::CreateStreamOnHGlobal(hGlobal, fDeleteOnRelease, &pMemStream);
    if (SUCCEEDED(hr))
    {
        hr = ::CoCreateInstance(CLSID_SpStream, NULL, CLSCTX_ALL, __uuidof(*ppStream), (void **)ppStream);
        if (SUCCEEDED(hr))
        {
            hr = (*ppStream)->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, pwfex);
            if (FAILED(hr))
            {
                (*ppStream)->Release();
                *ppStream = NULL;
            }
        }
        pMemStream->Release();
    }
    return hr;
}

我使用ISpStream完成了它。使用ispstream的Setbasestream函数将其绑定到istream,然后将ispvoice的输出设置为该ispstream

如果有人想要,这里是我的工作解决方案:


Eric,您如何找到GlobalAlloc调用获取HGLOBAL内存句柄所需的大小?我猜这取决于讲了多少话,但你怎么知道呢?你不需要知道。由::CreateStreamOnHGlobal管理的内存流将根据需要重新分配内存。我使用此示例作为实现将语音流传输到缓冲区的基础。但是当从IStream对象读取时,我总是读取零字节。查看stream对象,写入了字节(使用stream::Stat)。我需要使用IStream::LockRegion来获取数据吗?你成功做到了吗?