[Delphi与C ++中的SAPI 5.4 / 11日文TTS

问题描述 投票:0回答:1

[试图在Delphi 10.3中将MS Speech API v11与日语引擎(MS Haruka)一起使用]]

我有一个带有表单和按钮的示例应用程序。点击处理程序转到:

uses SpeechLib11_TLB; // Imported from "Microsoft Speech Object Library" v.B.0
procedure TForm1.Button1Click(Sender: TObject);
var
    v: ISpeechVoice;
begin
    v := CoSpVoice.Create();
    v.Speak('時間', SVSFDefault);
end;

这将导致错误“灾难性故障”(HRESULT 0x8000FFFF,E_UNEXPECTED)。我认为应该等效的代码可以在C ++项目中使用:

#include <windows.h>
#import "libid:d3c4a7f2-7d27-4332-b41f-593d71e16db1" rename_namespace("SAPI") //v11

int wmain()
{
    CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    {
        SAPI::ISpeechVoicePtr v;
        v.CreateInstance(__uuidof(SAPI::SpVoice));
        v->Speak(L"時間", SAPI::SVSFDefault);
    }
    CoUninitialize();
    return 0;
}

这行之有效。因此,SAPI 本身

在计算机上没有损坏。在两个项目中,平台均为Win32,而不是Win64。日语声音是默认声音(无需明确设置)。

[进一步的调试揭示了在Delphi方面,与在第一行引起相同错误E_UNEXPECTED之后立即调用v.Voice属性getter一样多。同时,如果您从Voice传递有效的语音令牌对象,则GetVoices() setter

将起作用。似乎语音对象在C ++中正确地将其自身初始化为默认值,但在Delphi项目中却以某种方式跳过了它。

尽管在带有SAPI 5.4的Delphi中,构造后仍可立即请求v.Voice。调用Speak()仍会引发E_UNEXPECTED。

C ++和Delphi之间在进程/线程范围执行上下文上有什么不同?

不是线程语言环境。 COM线程模型在这两者中都是共同的。

[同一Delphi代码使用英语短语和英语语音(MS Helen)。因此,无论有什么初始化失败,都可能是Haruka特有的。

SAPI 11运行时可用here。 TTS的语言数据为here


另一个数据点。我已经在Delphi中重写了SAPI逻辑以改为使用SAPI 5.4 OneCore(不适用于SAPI 5.4)。与5.4和11不同,它没有公开基于IDispatch的接口,并且在Delphi中特别笨拙,但是日语TTS可以工作。最初提出的问题仍然没有答案,但是至少有一种解决方法。我会写一个答案,但我不会接受。


但是,不是归咎于习惯与双重区别。我已经更改了逻辑,以使用自定义接口代替自动化接口使用SAPI 5.4适当

(类型库定义了两者),仍然从E_UNEXPECTED获得了Speak()。没有错误信息。

[试图在Delphi 10.3中将MS Speech API v11与日语引擎(MS Haruka)一起使用。我有一个带有表单和按钮的示例应用程序。点击处理程序变为:使用SpeechLib11_TLB; //从“ ...

delphi com text-to-speech
1个回答
1
投票

不是答案,而是解决方法。

Windows 10带有两种32位SAPI。有适当的SAPI 5.4(在system32\speech中),还有SAPI 5.4 OneCore(在system32\speech_onecore中)。后者,即使表面上是一样的,但暴露了不同的typelib-没有自动化支持,所有接口都是自定义的,而不是双重的。更重要的是,当您在Windows 10设置应用程序中下载日语TTS语音时,最终在OneCore(Sayaka, somehow, missing)下只有3种语音,而在5.4以下,只有一种Haruka。

© www.soinside.com 2019 - 2024. All rights reserved.