Delphi SAPI文本到语音

Delphi SAPI文本到语音,delphi,text-to-speech,sapi,createoleobject,Delphi,Text To Speech,Sapi,Createoleobject,首先:这不是一个复制品。我对“Delphi中的SAPI”主题有一个特别的问题 我在Delphi2009中使用了优秀的导入类型库指南,在组件调色板中获得了TSpVoice组件。这很有效。与 var SpVoice: TSpVoice; 我会写字 SpVoice.Speak('This is an example.', 1); 获取异步音频输出 第一个问题 根据文件,我将能够写作 SpVoice.Speak('This is an example.', 0); 为了获得同步音频输出,我得到

首先:这不是一个复制品。我对“Delphi中的SAPI”主题有一个特别的问题

我在Delphi2009中使用了优秀的导入类型库指南,在组件调色板中获得了TSpVoice组件。这很有效。与

var
  SpVoice: TSpVoice;
我会写字

SpVoice.Speak('This is an example.', 1);
获取异步音频输出

第一个问题

根据文件,我将能够写作

SpVoice.Speak('This is an example.', 0);
为了获得同步音频输出,我得到了一个EZeroDivide异常。为什么

第二个问题

但更重要的是,我希望能够动态创建SpVoice对象(我认为这是为了“后期绑定”SpVoice对象),部分原因是我的应用程序的所有会话中只有一小部分会使用它,部分原因是我不想假设最终用户系统上存在SAPI服务器

为此,我努力了

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: Variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SpVoice.Speak('this is a test', 0);
end;
这显然毫无作用!(将0替换为1会导致EZeroDivide异常。)

免责声明

我对COM/OLE自动化相当陌生。我为我在这篇文章中表现出的无知或愚蠢感到抱歉

更新 为了让每个人都遇到与我相同的问题,François的视频解释了SAPI/Windows中存在一个bug(某些地方存在不兼容),这使得以下代码引发了EZeroDivide异常:

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SpVoice.Speak('This is a text.');
end;
如视频所示,解决方案是改变FPU控制字:

procedure TForm1.FormClick(Sender: TObject);
var
  SpVoice: variant;
  SavedCW: Word;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  SavedCW := Get8087CW;
  Set8087CW(SavedCW or $4);
  SpVoice.Speak('This is a text.');
  Set8087CW(SavedCW);
end;

此外,如果你想异步播放声音,那么你必须确保播放器没有超出范围

你可能会发现在电视上看到的东西很有趣 你会得到你要找的“指南”。。。
(我猜你是在Vista或+上,因为零除法在XP上没有发生)

我在Delphi XE2中也遇到了同样的问题。问题中提出的
Set8087CW(SavedCW或$4)
解决方案对我不起作用。它只是用另一个浮点异常替换了除零异常

对我来说,成功的原因是:

SavedCW := Get8087CW;
SetFPUExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);
SpVoice.Speak('All floating point exceptions disabled!', 0);
Set8087CW(SavedCW);

啊,非常感谢!所以这不仅仅是因为我愚蠢!顺便说一句:如果你想获得这段视频的荣誉,请随意删除你名字旁边的问号!:)