6

我一直试图弄清楚如何使用 Windows SAPI 5.1 将文本“说”到内存缓冲区中,但到目前为止还没有成功,尽管它看起来应该很简单。

一个将合成语音流式传输到 .wav 文件的示例,但没有关于如何将其流式传输到内存缓冲区的示例。

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

有谁知道该怎么做?

谢谢!

4

3 回答 3

7

查看 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;
}
于 2010-05-11T21:02:57.983 回答
2

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

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

https://github.com/itsyash/MS-SAPI-demo

于 2014-06-01T07:03:16.947 回答
0

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

于 2010-05-07T04:13:43.173 回答