AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Warten bis Sprachausgabe beendet
Thema durchsuchen
Ansicht
Themen-Optionen

Warten bis Sprachausgabe beendet

Ein Thema von Amateurprofi · begonnen am 13. Okt 2013 · letzter Beitrag vom 15. Okt 2013
Antwort Antwort
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#1

Warten bis Sprachausgabe beendet

  Alt 13. Okt 2013, 15:48
Ich möchte per Sprachausgabe einen Text ausgeben und solange warten, bis entweder der Text komplett gesprochen wurde, oder irgendeine Taste gedrückt wird.
Wenn der Text komplett gesprochen wurde, möchte ich einen Timer "enablen", und den Text nach einer gewissen Wartezeit erneut ausgeben.
Wurde aber durch Drücken einer Taste abgebrochen, soll der Timer nicht "enabled" werden.

Mein untenstehender Versuch, zunächst einmal zu warten, bis entweder der Text komplett gesprochen wurde, oder eine Taste gedrückt wurde, funktioniert nicht, weil das MsgWaitForMultipleObjects zurückkehrt, bevor der Text komplett gesprochen wurde, auch wenn keine Taste gedrückt wurde.

Wie kann ich das realisieren?
Und Frage am Rande: Muss ich Voice beim beenden des Programms irgenwie "freigeben" oder brauche ich mich darum nicht kümmern?

Delphi-Quellcode:
procedure TMain.FormShow(Sender: TObject);
begin
   Voice:=CreateOleObject('SAPI.SpVoice');
end;

procedure TMain.Button1Click(Sender: TObject);
var Reason:Cardinal; Ev:THandle;
begin
   Edit1.Text:='';
   Application.ProcessMessages;
   Voice.Speak('Hallo, ich warte jetzt, bis der Text zu ende ist, oder eine '+
               'Taste gedrückt wird.', 1);
   Ev:=Voice.SpeakCompleteEvent;
   Reason:=MsgWaitForMultipleObjects(1, Ev, False, Infinite, QS_Key);
   Edit1.Text:=IntToStr(Reason);
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Gerd01

Registriert seit: 18. Mär 2005
Ort: NRW
117 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Warten bis Sprachausgabe beendet

  Alt 13. Okt 2013, 17:41
Du könntest die SpeechLib_TLB.pas benutzen.
Dort ist das Server-Object
// ************************************************** *******************//
// OLE-Server-Proxy-Klassendeklaration
// Server-Objekt : TSpVoice
// Hilfe-String : SpVoice Class
// Standard-Interface: ISpeechVoice
// Def. Intf. DISP? : No
// Ereignis-Interface: _ISpeechVoiceEvents
// TypeFlags : (2) CanCreate
// ************************************************** *******************//

TSpVoice = class(TOleServer)

Mit SpVoice1.Skip('Sentence', MaxInt) kannst du die Sprachausgabe stoppen
Mit SpVoice1.Pause pausieren etc. Der OleServer läßt keine Wünsche offen.
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#3

AW: Warten bis Sprachausgabe beendet

  Alt 13. Okt 2013, 22:30
@Gerd01:
Danke, jedoch leider löst das nicht mein Problem.
Ich möchte nicht die Ausgabe der Sprache beenden, pausieren etc.
Sondern ich möchte solange warten, bis
entweder der zu sprechende Text komplett gesprochen wurde
oder eine Taste gedrückt wurde.
Und ich brauche eine Information, ob "das Warten" beendet wurde, weil der Text komplett gesprochen wurde oder weil eine Taste gedrückt wurde.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#4

AW: Warten bis Sprachausgabe beendet

  Alt 14. Okt 2013, 16:37
Dein Code entspricht ja ziemlich genau dem Beispiel von Microsoft.
Funktioniert es* denn, wenn du mit WaitUntilDone oder WaitForSingleObject wartest bzw. was ist der Rückgabewert von MsgWaitForMultipleObjects?

* Damit meine ich natürlich nur das Warten auf die Sprachausgaben
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Warten bis Sprachausgabe beendet

  Alt 15. Okt 2013, 00:33
@Bug:
WaitUntilDone
funktioniert, wartet also bis entweder der Text gesprochen ist, oder die als Parameter mitgegebene Zeit abgelaufen ist.

WaitForSingleObject
dto

MsgWaitForMultipleObjects
Der Rückgabewert ist immer = 1
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#6

AW: Warten bis Sprachausgabe beendet

  Alt 15. Okt 2013, 01:01
Das bedeutet imho, dass dein Problem beim Aufwecken durch den Tastendruck (QS_Key) liegt und nicht bei der Sprachausgabe.

Eventuell könnte man es so beheben:
Delphi-Quellcode:
procedure TMain.Button1Click(Sender: TObject);
var Reason:Cardinal; Ev:THandle;
begin
   Edit1.Text:='';
   Application.ProcessMessages;
   Voice.Speak('Hallo, ich warte jetzt, bis der Text zu ende ist, oder eine '+
               'Taste gedrückt wird.', 1);
   Ev:=Voice.SpeakCompleteEvent;
   // >>>
   speechCanceled := false; // "global"
   repeat
     Reason:=MsgWaitForMultipleObjects(1, Ev, False, Infinite, QS_Key);
     if Reason = (WAIT_OBJECT_0 + 1) then
       Application.ProcessMessages;
   until speechCanceled or (Reason = WAIT_OBJECT_0);
   // <<<
   Edit1.Text:=IntToStr(Reason);
end;
speechCanceled könnte dann bei Bedarf (also einer gewünschten Tasten-Aktion) in der Message-Behandlung des Formulars gesetzt werden.

Geändert von BUG (15. Okt 2013 um 02:06 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Warten bis Sprachausgabe beendet

  Alt 15. Okt 2013, 04:29
@Bug:
Das wird so nicht funktionieren, weil (zumindest bei mir) MsgWaitForMultipleObjects sofort zurückkehrt und konstant 1 als Resultat liefert. Zum Drücken einer Taste kommt es also gar nicht.

Ich habe mein Problem jetzt so gelöst:

Delphi-Quellcode:
PROCEDURE TMain.Speak(Const S:String);
var Res:DWord; EV:THandle;
begin
   Timer.Enabled:=False;
   Voice.Skip('SENTENCE',MaxInt);
   fSpeakCancelled:=False;
   Voice.Speak(S,1);
   EV:=Voice.SpeakCompleteEvent;
   repeat
      Res:=WaitForSingleObject(Ev,100);
      if Res=WAIT_TIMEOUT then Application.Processmessages;
   until (Res<>WAIT_TIMEOUT) or SpeakCancelled;
   if not SpeakCancelled then Timer.Enabled:=True;
end;
fSpeakCancelled wird in FormShortCut dann auf True gesetzt, wenn eine Taste gedrückt wird.
Mit Voice.WaitUntilDone klappte das merkwürdigerweise nicht.
Danke für Deinen Hinweis auf WaitForSingleObject, das ich von vornherein verworfen hatte.
Da ich ja nicht nur auf das Ende der Sprachausgabe sondern parallel auch auf Tastendrücke warten wollte war ich auf MsgWaitForMultipleObjects fixiert.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Gerd01

Registriert seit: 18. Mär 2005
Ort: NRW
117 Beiträge
 
Delphi XE2 Professional
 
#8

AW: Warten bis Sprachausgabe beendet

  Alt 15. Okt 2013, 10:15
@Gerd01:
Danke, jedoch leider löst das nicht mein Problem.
Ich möchte nicht die Ausgabe der Sprache beenden, pausieren etc.
Sondern ich möchte solange warten, bis
entweder der zu sprechende Text komplett gesprochen wurde
oder eine Taste gedrückt wurde.
Und ich brauche eine Information, ob "das Warten" beendet wurde, weil der Text komplett gesprochen wurde oder weil eine Taste gedrückt wurde.
Ja ich verstehe schon was du meinst. Folgende Ereignisse
stehen bei der Komponente aber zur Verfügung:


property OnStartStream: TSpVoiceStartStream read FOnStartStream write FOnStartStream;
property OnEndStream: TSpVoiceEndStream read FOnEndStream write FOnEndStream;
property OnVoiceChange: TSpVoiceVoiceChange read FOnVoiceChange write FOnVoiceChange;
property OnBookmark: TSpVoiceBookmark read FOnBookmark write FOnBookmark;
property OnWord: TSpVoiceWord read FOnWord write FOnWord;
property OnSentence: TSpVoiceSentence read FOnSentence write FOnSentence;
property OnPhoneme: TSpVoicePhoneme read FOnPhoneme write FOnPhoneme;
property OnViseme: TSpVoiceViseme read FOnViseme write FOnViseme;
property OnAudioLevel: TSpVoiceAudioLevel read FOnAudioLevel write FOnAudioLevel;
property OnEnginePrivate: TSpVoiceEnginePrivate read FOnEnginePrivate write FOnEnginePrivate;
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Warten bis Sprachausgabe beendet

  Alt 15. Okt 2013, 23:16
Danke, Gerd.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz