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

时间:2010-11-16 18:29:37

标签: text-to-speech sapi

我正在编写一个包含两个字符的应用程序,每个应该使用不同的文本到语音语音。我们仍在使用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在我分配它的位置和我访问它的位置之间没有变化(因此没有其他任何干扰)。

有什么想法吗?

非常感谢你的时间。我真的很感激!

1 个答案:

答案 0 :(得分:1)

......没关系。

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

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