使用语音令牌与 SAPI 5.1 文本到语音交换语音

发布于 2024-10-03 12:07:54 字数 1733 浏览 8 评论 0原文

我正在编写一个应用程序,其中有两个字符,每个字符应该使用不同的文本到语音的声音。我们仍在使用 Windows XP,因此仅限于 SAPI 5.1。

我想做的是,当创建一个角色时,为它分配一个代表其声音的标记:

//female voices
        HRESULT hr;
        if (sceneObjects.at(characterLocation).gender == FEMALE){
            if (sceneObjects.at(characterLocation).age == ADULT){
                hr = SpFindBestToken(SPCAT_VOICES, L"Name=VW Kate", L"", &pToken);
                if (FAILED(hr)){
                    hr = SpFindBestToken(SPCAT_VOICES, L"Gender=Female",L"",&pToken);
                    //if we fail load the default voice
                    if(FAILED(hr)) pToken = NULL;
                }
                sceneObjects.at(characterLocation).voiceToken = pToken;
            }
            else{
                hr = SpFindBestToken(SPCAT_VOICES, L"Gender=Female", L"Name=Microsoft Mary", &pToken);
                //if we fail load the default voice
                if(FAILED(hr)) pToken = NULL;
                //s = L"<pitch middle=\"+10\">"+s+L"</pitch>";
                sceneObjects.at(characterLocation).voiceToken = pToken;
            }
        }

然后当我真正想要它说话时,我将角色作为参数传递到文本到语音线程中并分配声音它的标记:

DWORD WINAPI DIGuy::sayMessage(LPVOID lpParam){
HRESULT hres;
try{

    ThreadParam * param = (ThreadParam *)lpParam;
    wstring s = param->message;
    wstring characterName = param->sceneObject.name;

    ISpVoice * pVoice;
    pVoice->SetVoice(param->sceneObject.voiceToken);

我的问题是,当我进行 SetVoice 调用时,无论我为我的角色分配什么声音,我都会得到默认的系统语音。在调试模式下运行显示 voiceToken 不为空(这将导致加载默认语音),并且返回的 voiceToken 不会因我切换系统默认语音而改变(因此它也不会自动映射到默认语音),并且 voiceToken 在我分配它的位置和访问它的位置之间不会改变(因此没有其他干扰)。

有什么想法吗?

非常感谢您抽出时间。我真的很感激!

I am writing an application that has two characters in it and each should use a different text-to-speech voice. We're still using Windows XP so we're restricted to SAPI 5.1.

What I am trying to do is when a character is created, assign it a token that represents its voice:

//female voices
        HRESULT hr;
        if (sceneObjects.at(characterLocation).gender == FEMALE){
            if (sceneObjects.at(characterLocation).age == ADULT){
                hr = SpFindBestToken(SPCAT_VOICES, L"Name=VW Kate", L"", &pToken);
                if (FAILED(hr)){
                    hr = SpFindBestToken(SPCAT_VOICES, L"Gender=Female",L"",&pToken);
                    //if we fail load the default voice
                    if(FAILED(hr)) pToken = NULL;
                }
                sceneObjects.at(characterLocation).voiceToken = pToken;
            }
            else{
                hr = SpFindBestToken(SPCAT_VOICES, L"Gender=Female", L"Name=Microsoft Mary", &pToken);
                //if we fail load the default voice
                if(FAILED(hr)) pToken = NULL;
                //s = L"<pitch middle=\"+10\">"+s+L"</pitch>";
                sceneObjects.at(characterLocation).voiceToken = pToken;
            }
        }

and then when I actually want it to speak, I pass in the character as a parameter into the text to speech thread and assign the voice its token:

DWORD WINAPI DIGuy::sayMessage(LPVOID lpParam){
HRESULT hres;
try{

    ThreadParam * param = (ThreadParam *)lpParam;
    wstring s = param->message;
    wstring characterName = param->sceneObject.name;

    ISpVoice * pVoice;
    pVoice->SetVoice(param->sceneObject.voiceToken);

My problem is no matter what voice I assign to my character when I do the SetVoice call I get the default system voice. Running in debug mode shows that the voiceToken is not null (which would cause the default voice to load) and that the voiceToken returned does not change due to my switching the system default voice (so it's not automatically mapping to default there, either), and that the voiceToken doesn't change between where I assign it and where I access it (so there's nothing else interfering).

Any ideas?

Thanks so much for your time. I really appreciate it!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

巨坚强 2024-10-10 12:07:54

...没关系。

对于其他感到困惑的人,在完成此函数调用之前,您无法设置 pVoice:

hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

...never mind.

For anyone else who gets confused, you can't set pVoice until you've done this function call:

hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文