delphi利用微软SAPI实现语音控制(Delphi,TTS,SR,灰色代码)_

2018-10-30

和群里的大小牛们聊天时突发奇想,做了这个东西,通过麦克风发送命令控制电脑。程序没有什么深奥之处,调用了微软的SAPI实现语音识别,和文本语音,关于文本语音可参见我以前的文章。使用语音识别时最好根据个人情况进行语音训练,测试程序提供了鼠标移动,单击,运行指定程序等基本功能,可以酌情添加做成更丰富功能的软件。

unit main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleServer, SpeechLib_TLB,ActiveX, ComCtrls,ControlCenter;

type
TadeSoundControl = class(TForm)
SpVoice1: TSpVoice;
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Memo1: TMemo;
SpSharedRecoContext1: TSpSharedRecoContext;
ProgressBar1: TProgressBar;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Speecker(id:Integer;speech:Integer;str:string);
procedure SpSharedRecoContext1SoundStart(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant);
procedure SpSharedRecoContext1SoundEnd(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant);
procedure SpSharedRecoContext1Recognition(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant;
RecognitionType: TOleEnum; const Result: ISpeechRecoResult);
procedure FormCreate(Sender: TObject);
procedure SpSharedRecoContext1AudioLevel(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant;
AudioLevel: Integer);
procedure vg2Background1Click(Sender: TObject);

private
SRGrammar: ISpeechRecoGrammar;
CmdLine:string;
ControlActive:Boolean;
public
procedure Log(s1:string);overload;
procedure Log(s1:string;s2:string);overload;

end;

var
adeSoundControl: TadeSoundControl;

implementation

{$R *.dfm}
procedure TadeSoundControl.Speecker(id:Integer;speech:Integer;str:string);
var
SOToken: ISpeechObjectToken;
SOTokens: ISpeechObjectTokens;
begin
SOTokens := SpVoice1.GetVoices('', '');
SOToken := SOTokens.Item(id);
SpVoice1.Voice := SOToken;
SpVoice1.Rate:=speech;
SpVoice1.Volume:=100;
spvoice1.Speak(str,SVSFDefault);
end;

procedure TadeSoundControl.Button1Click(Sender: TObject);
begin
Speecker(StrToInt(Edit2.Text),StrToInt(Edit3.Text),Edit1.Text);
end;
procedure TadeSoundControl.Log(s1:string);
begin

Memo1.Lines.Add(s1);
end;
procedure TadeSoundControl.Log(s1:string;s2:string);
begin
Memo1.Lines.Add(s1+s2);
end;
procedure TadeSoundControl.Button2Click(Sender: TObject);
begin
Log('ade');
end;

procedure TadeSoundControl.Button3Click(Sender: TObject);
begin
Log('fuck','ade');
end;

procedure TadeSoundControl.SpSharedRecoContext1SoundStart(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant);
begin
Log('Sound Start');
end;

procedure TadeSoundControl.SpSharedRecoContext1SoundEnd(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant);
begin
Log('Sound End');
end;

procedure TadeSoundControl.SpSharedRecoContext1Recognition(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant;
RecognitionType: TOleEnum; const Result: ISpeechRecoResult);
var
adeString:string;
pt:TPoint;
h:HWND;
begin

with Result.PhraseInfo do
begin
adeString:=GetText(0, -1, True);
end;
if adeString='小二' then
begin
ControlActive:=True;
Speecker(3,6,'老爷,小的在!');
Self.Show;
Exit;
end;
if adeString='退下' then
begin
ControlActive:=False;
Speecker(3,5,'是,老爷。小的先退了');
Self.Hide;
//ShowWindow(Self.Handle,SW_HIDE);
Exit;
end;
if adeString='单击' then
begin
GetCursorPos(pt);
h:=WindowFromPoint(pt);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
Exit;
end;
if adeString='左移' then
begin
GetCursorPos(pt);
SetCursorPos(pt.X-150,pt.Y);
Exit;
end;
if adeString='右移' then
begin
GetCursorPos(pt);
SetCursorPos(pt.X+150,pt.Y);
Exit;
end;
if adeString='上移' then
begin
GetCursorPos(pt);
SetCursorPos(pt.X,pt.Y-150);
Exit;
end;
if adeString='下移' then
begin
GetCursorPos(pt);
SetCursorPos(pt.X,pt.Y+150);
Exit;
end;
if adeString<>'命令结束' then
begin
if CmdLine='' then
CmdLine:=adeString
else
CmdLine:=CmdLine+'|'+adeString;
log('正在等待下一条命令!命令结束请说"命令结束"');
end
else
begin
execCommand(CmdLine);
Log('已经成功执行命令:'+CmdLine);
CmdLine:='';
end;
end;

procedure TadeSoundControl.FormCreate(Sender: TObject);
begin
SpSharedRecoContext1.EventInterests:=SREAllEvents;
//SpSharedRecoContext.CreateGrammar(0);
SRGrammar := SpSharedRecoContext1.CreateGrammar(0);
SRGrammar.CmdLoadFromFile('adeCmdLine.xml', SLODynamic);
SRGrammar.CmdSetRuleIdState(0, SGDSActive);
end;

procedure TadeSoundControl.SpSharedRecoContext1AudioLevel(ASender: TObject;
StreamNumber: Integer; StreamPosition: OleVariant; AudioLevel: Integer);
begin
progressbar1.Position:=AudioLevel;
end;

procedure TadeSoundControl.vg2Background1Click(Sender: TObject);
begin
ControlActive:=False;
end;

end.

阅读274