2010-06-13 6 views
11

Zunächst einmal: Dies ist kein Duplikat von Delphi and SAPI. Ich habe ein spezifisches Problem mit dem Thema "SAPI in Delphi".Delphi SAPI Text-zu-Sprache

Ich habe die hervorragende Import-Typ-Bibliothek Guide in Delphi 2009 verwendet, um eine TSpVoice-Komponente in der Komponentenpalette zu erhalten. Das funktioniert großartig. Mit

var 
    SpVoice: TSpVoice; 

kann ich schreiben

SpVoice.Speak('This is an example.', 1); 

asynchronen Audio-Ausgang zu erhalten.

Erste Frage

Gemäß der Dokumentation, würde ich in der Lage sein

zu schreiben
SpVoice.Speak('This is an example.', 0); 

Synchron Audio-Ausgang zu erhalten, sondern erhalte ich eine EZeroDivide Ausnahme. Warum ist das?

Zweite Frage

Aber noch wichtiger ist, würde Ich mag Lage sein, das SpVoice Objekt dynamisch zu erstellen (ich denke, das genannt wird „late-bind“ das SpVoice Objekt), zum Teil, weil nur Ein sehr kleiner Teil aller Sitzungen meiner App wird es verwenden, und teilweise, weil ich nicht davon ausgehen möchte, dass der SAPI-Server auf dem System des Endanwenders existiert.

Zu diesem Zweck habe ich versucht,

procedure TForm1.FormClick(Sender: TObject); 
var 
    SpVoice: Variant; 
begin 
    SpVoice := CreateOleObject('SAPI.SpVoice'); 
    SpVoice.Speak('this is a test', 0); 
end; 

die scheinbar gar nichts tut! (Ersetzen der 0 mit 1 gibt mir die EZeroDivide Ausnahme.)

Haftungsausschluss

Ich bin ziemlich neu zu COM/OLE-Automatisierung. Es tut mir leid für jede Unwissenheit oder Dummheit von mir in diesem Beitrag gezeigt ...

aktualisieren

Zum Wohle jeder das gleiche Problem auftritt, wie ich es tat, um das Video von François erklärt gibt es einen Fehler in SAPI/Fenster (irgendwo einige Inkompatibilität), die den folgenden Code macht erhöhen EZeroDivide Ausnahme:

procedure TForm1.FormClick(Sender: TObject); 
var 
    SpVoice: variant; 
begin 
    SpVoice := CreateOleObject('SAPI.SpVoice'); 
    SpVoice.Speak('This is a text.'); 
end; 

die Lösung wird wie durch das Video präsentiert, die FPU-Steuerwort zu verändern:

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; 

Und wenn Sie einen Sound asynchron spielen möchten, müssen Sie sicherstellen, dass der Player nicht aus dem Oszilloskop geht!

Antwort

4

Sie finden möglicherweise interessant zu sehen this CodeRage 4 session auf "Speech Enabling Delphi Applications (zip)" Sie erhalten die "how-to", die Sie suchen ... (und ich glaube, Sie sind auf Vista oder + wie die Zero Divide nicht auf XP passiert)

+0

Ah, vielen Dank! Also war ich nicht einfach nur dumm! –

+0

BTW: Fühlen Sie sich frei, das Fragezeichen neben Ihrem Namen zu entfernen, wenn Sie für das Video Kredit nehmen möchten! :) –

1

Ich hatte das gleiche Problem in Delphi XE2. Die in der Frage vorgestellte Set8087CW(SavedCW or $4) Lösung funktionierte nicht für mich. Es hat lediglich die Division durch Null-Ausnahme durch eine andere Gleitkommaausnahme ersetzt.

Was für mich arbeiten, ist dies:

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