2012-08-24 5 views
4

다음 작품 (델파이 7) 작동하지 않습니다 : "동기화"모드 (SVSFDefault 플래그)에서SAPI : 비동기 연설 완벽하게

procedure TMainForm.SayIt(s:string); // s is the string to be spoken 
var 
voice: OLEVariant; 
begin 
    memo1.setfocus; 
    voice := CreateOLEObject ('SAPI.SpVoice'); 
    voice.Voice := voice.GetVoices.Item(combobox1.ItemIndex); // current voice selected 
    voice.volume := tbVolume.position; 
    voice.rate := tbRate.position; 
    voice.Speak (s, SVSFDefault); 
end; 

위의 작품,하지만 난 깃발을 변경하는 경우 ~ SVSFlagsAsync 비동기 모드에서 사운드를 재생하려고 시도하면 소리가 나지 않습니다. 오류 메시지는 표시되지 않지만 스피커에서는 아무 것도 재생되지 않습니다.

무엇이 문제일까요? Delphi의 Imports 폴더에 SpeechLib_TLB 단위가 있습니다.

편집 :

감사합니다, 브루노는 윈도우 XP입니다.

+0

오래 전 SAPI로 게임을했습니다. 비동기로 만들기 위해 대기열이있는 스레드를 만들었습니다.이 스레드는 꽤 잘 작동하는 것으로 나타났습니다. – ComputerSaysNo

답변

6

SVSFlagsAsync 플래그를 사용하면 음성 스트림이 내부 버퍼에 대기하여 음성 서비스에서 실행되기를 기다리고 있습니다. 따라서 음성 개체의 수명과 관련이 있습니다. 로컬 변수를 사용하면 사운드를 실행하기 전에 인스턴스가 파괴됩니다.

으로 당신이 WaitUntilDone 방법

voice.Speak (s, SVSFlagsAsync); 
    repeat Sleep(100); until voice.WaitUntilDone(10); 

를 사용하여 사운드를 기다리거나 당신이 정의를 형성에 voice 변수를 선언 할 수 있습니다 해결.

TMainForm = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    voice: OLEVariant; 
    procedure SayIt(const s:string); 
    end; 

var 
    MainForm: TMainForm; 

implementation 

uses 
    ComObj; 

{$R *.dfm} 
procedure TMainForm.SayIt(const s:string); // s is the string to be spoken 
const 
    SVSFDefault = 0; 
    SVSFlagsAsync = 1; 
    SVSFPurgeBeforeSpeak= 2; 
begin 
    memo1.setfocus; 
    voice.Voice := voice.GetVoices.Item(combobox1.ItemIndex); // current voice selected 
    voice.volume := tbVolume.position; 
    voice.rate := tbRate.position; 
    voice.Speak (s, SVSFlagsAsync {or SVSFPurgeBeforeSpeak}); 
end; 


procedure TMainForm.Button1Click(Sender: TObject); 
begin 
    SayIt('Hello'); 
end; 

procedure TMainForm.FormCreate(Sender: TObject); 
begin 
    voice := CreateOLEObject('SAPI.SpVoice'); 
end; 

procedure TMainForm.FormDestroy(Sender: TObject); 
begin 
    voice := Unassigned; 
end; 

end. 

후기 바인딩을 사용 중이므로 SpeechLib_TLB 단위가 필요하지 않습니다.

+3

WaitUntilDone은 그것을 동기식으로 만듭니다. 그래서 필요한 것은 아닙니다. 마지막 단락은 다음과 같이 설명 할 수 있습니다. import lib를 사용하는 경우 초기 바인딩으로 전환 할 수 있습니다. +1 –