2010-06-13 225 views
11

首先:这不是Delphi and SAPI的重复。我在“德尔菲SAPI”主题中遇到了特定的问题。Delphi SAPI文字转语音

我在Delphi 2009中使用了优秀的导入类型库指南来获取组件面板中的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自动化。我感谢我在这个岗位表现出任何的无知或愚蠢对不起......

更新

对于大家遇到相同的问题,因为我做的好处,由弗朗索瓦视频说明存在SAPI错误/ Windows的(一些不兼容的地方),这使得下面的代码提高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; 

此外,如果您想异步播放声音,那么您必须确保播放器不会超出范围!

回答

4

您可能会感兴趣在"Speech Enabling Delphi Applications (zip)"上看到this CodeRage 4 session 您将看到您正在寻找的“how-to”... (我猜你是在Vista或+上,因为零分频没有在XP上发生)

+0

啊,非常感谢你!所以,这不仅仅是我愚蠢,然后! – 2010-06-14 00:15:55

+0

顺便说一句:如果你想获得视频的荣誉,随意删除你的名字旁边的问号! :) – 2010-06-14 00:34:06

1

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

做什么工作对我来说是这样的:

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