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

使用SAPI5.4无法正确朗读非英文文本的问题求助

解决SAPI5.4无法朗读非英文文本的问题

核心问题分析

你的代码中硬编码的语音token注册表路径存在转义错误:C++宽字符串(L"")中的反斜杠\是转义字符,必须写成\\才能被正确解析为路径分隔符。原路径会被错误解析,导致中文语音token加载失败,程序实际使用默认英文语音,因此中文内容被跳过,日语同理。

修正步骤

1. 修复注册表路径转义

将硬编码路径中的单反斜杠替换为双反斜杠:

SpGetTokenFromId(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\TTS_MS_ZH-CN_HUIHUI_11.0", &cpVoiceToken);

2. 验证语音token加载状态

在SetVoice后添加错误检查,确认语音切换是否成功:

hr = pVoice->SetVoice(cpVoiceToken);
if (FAILED(hr)) {
    wprintf(L"Failed to set Chinese voice, error code: 0x%08X\n", hr);
}

3. 更可靠的语音token获取方式(推荐)

避免硬编码注册表路径,用SpEnumTokens枚举系统已安装的语音,提升兼容性:

// 枚举中文语音(语言ID:0x804)
CComPtr<IEnumSpObjectTokens> cpEnum;
hr = SpEnumTokens(SPCAT_VOICES, L"Language=804", NULL, &cpEnum);
if (SUCCEEDED(hr)) {
    cpEnum->Next(1, &cpVoiceToken, NULL);
}

常用语言ID参考:中文(简体)0x804、英文(美国)0x409、日语0x411

4. 多语言混合朗读处理

若需同时朗读多种语言,建议为不同语言内容切换对应语音:

// 用中文语音朗读中文
hr = pVoice->Speak(L"你好", SPF_DEFAULT, NULL);
// 切换到英文语音朗读英文
CComPtr<ISpObjectToken> cpEngToken;
SpGetTokenFromId(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\TTS_MS_EN-US_DAVID_11.0", &cpEngToken);
pVoice->SetVoice(cpEngToken);
hr = pVoice->Speak(L"Hello", SPF_DEFAULT, NULL);

5. 日语朗读前置条件

要朗读日语,需先在系统设置中安装日语TTS语音包(路径:Windows设置→时间和语言→语音→添加语音包),再加载对应日语语音token:

SpGetTokenFromId(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\TTS_MS_JA-JP_HARUKA_11.0", &cpVoiceToken);

完整修正代码

#include <sapi.h>
#include <atlbase.h>
#include <atlstr.h>
#pragma warning (suppress: 4996)
#include <sphelper.h>
#include <wchar.h>

int main(int argc, char* argv[])
{
    ISpVoice* pVoice = NULL;

    if (FAILED(::CoInitialize(NULL)))
        return FALSE;

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);
    if (FAILED(hr)) {
        ::CoUninitialize();
        return FALSE;
    }

    CComPtr<ISpObjectToken> cpVoiceToken;
    // 修复转义后的中文语音路径
    hr = SpGetTokenFromId(L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\TTS_MS_ZH-CN_HUIHUI_11.0", &cpVoiceToken);
    if (SUCCEEDED(hr)) {
        hr = pVoice->SetVoice(cpVoiceToken);
        if (SUCCEEDED(hr)) {
            hr = pVoice->Speak(L"你好 Hello", SPF_DEFAULT, NULL);
        } else {
            wprintf(L"Failed to set voice, error: 0x%08X\n", hr);
        }
    } else {
        wprintf(L"Failed to get voice token, error: 0x%08X\n", hr);
    }

    // 清理资源
    if (pVoice) pVoice->Release();
    ::CoUninitialize();

    return 0;
}

额外注意事项

  • 确保项目设置为Unicode字符集(VS2022默认开启,可在项目属性→常规→字符集修改)
  • 确认系统已正确安装目标语言的TTS语音库
  • Windows 10/11中部分旧版语音库可能被替换,可通过「语音设置」查看已安装语音的注册表路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:40:22