You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows.Media.SpeechSynthesis能否像SAPI 5.3那样设置音频流格式?

Windows.Media.SpeechSynthesis 音频格式控制与文件写入指南

针对你从SAPI切换到C++/WinRT的SpeechSynthesis时遇到的几个问题,我整理了对应的解决方案和细节:

1. 类似SPBindToFile的文件绑定与格式设置方法

SpeechSynthesis没有直接对应SPBindToFile的API,但可以通过先设置合成格式,再将合成后的流写入文件的方式实现类似效果:

  • 首先,你可以通过SpeechSynthesizer的Options属性(SpeechSynthesisOptions)指定音频格式,但要注意:格式必须是当前选中语音所支持的格式。
  • 合成完成后,将SpeechSynthesisStream复制到目标文件的输出流即可完成写入。

你可以先获取当前语音支持的所有格式,再选择合适的格式设置:

#include <winrt/Windows.Media.SpeechSynthesis.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Streams.h>

using namespace winrt;
using namespace Windows::Media::SpeechSynthesis;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;

// 获取默认语音并查看其支持的格式
auto synthesizer = SpeechSynthesizer{};
auto voice = synthesizer.DefaultVoice();
auto supportedFormats = voice.SupportedAudioFormats();

// 选择一个支持的格式(比如24kHz/24位单声道PCM)
for (auto const& format : supportedFormats)
{
    if (format.SampleRate() == 24000 && format.BitsPerSample() == 24)
    {
        synthesizer.Options().AudioFormat(format);
        break;
    }
}

然后合成并写入文件:

// 合成文本
auto stream = co_await synthesizer.SpeakTextAsync(L"Hello from C++/WinRT Speech Synthesis");

// 创建或打开目标文件
auto folder = co_await KnownFolders::DocumentsLibrary();
auto file = co_await folder.CreateFileAsync(L"SpeechOutput.wav", CreationCollisionOption::ReplaceExisting);

// 将合成流写入文件
auto fileStream = co_await file.OpenAsync(FileAccessMode::ReadWrite);
co_await RandomAccessStream::CopyAndCloseAsync(stream, fileStream);

2. 是否只能获取16kHz/16位单声道的波形流?

不是的。默认情况下可能会使用16kHz/16位单声道的格式,但不同的TTS语音(比如微软的Neural Voices)支持多种音频格式,包括:

  • 不同采样率(16kHz、24kHz、48kHz等)
  • 不同位深(16位、24位)
  • 部分语音还支持压缩格式(比如MP3)

你可以通过VoiceInformation.SupportedAudioFormats获取当前语音支持的所有格式列表,再根据需求选择合适的格式设置到SpeechSynthesisOptions.AudioFormat即可。

3. SpeechSynthesisStream 的数据是预计算还是实时编码?

当你调用SpeakTextAsync或SpeakSsmlAsync完成后,返回的SpeechSynthesisStream已经包含了完整的、编码好的音频数据,并非预计算的原始数据。也就是说:

  • 流的Size属性在合成完成后就是有效的,代表音频数据的总字节数
  • 当你读取流数据(比如播放或写入文件)时,不需要再进行实时编码,直接读取的就是最终的音频字节

这和SAPI的合成流程类似,合成过程在异步方法完成时就已经完成,流里是直接可用的音频数据。

内容的提问来源于stack exchange,提问作者Appolon Sharov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:40:16