Delphi SAPI Text-to-Speech
Tout d'abord: ce n'est pas un doublon de Delphi et SAPI. J'ai un problème spécifique avec le "SAPI en Delphi" objet.
J'ai utilisé l'excellent Type d'Importation de la Bibliothèque-guide en Delphi 2009 pour obtenir un TSpVoice composant dans la palette de composants. Cela fonctionne très bien. Avec
var
SpVoice: TSpVoice;
Je peux écrire
SpVoice.Speak('This is an example.', 1);
pour obtenir asynchrone de sortie audio.
Première question
Selon la documentation, je serais capable d'écrire
SpVoice.Speak('This is an example.', 0);
pour obtenir synchrone sortie audio, mais au lieu de cela, je reçois un EZeroDivide exception. Pourquoi?
Deuxième question
Mais plus important encore, je voudrais être en mesure de créer le SpVoice objet dynamiquement (je pense que c'est appelé à la "fin de l'-lier" la SpVoice objet), en partie parce que seule une très petite fraction de toutes les sessions de mon application va utiliser, et en partie parce que je ne veux pas présumer de l'existence de la SAPI server sur le système de l'utilisateur final.
À cette fin, j'ai essayé
procedure TForm1.FormClick(Sender: TObject);
var
SpVoice: Variant;
begin
SpVoice := CreateOleObject('SAPI.SpVoice');
SpVoice.Speak('this is a test', 0);
end;
qui, apparemment, ne fait rien du tout! (En remplaçant le 0 par 1 me donne la EZeroDivide exception).
Avertissement
Je suis plutôt nouveau COM/OLE automation. Je suis désolé pour tout à l'ignorance ou la stupidité montré par moi dans ce post...
Mise à jour
Pour le bénéfice de tout le monde rencontre le même problème que moi, la vidéo de François expliqué il y a un bug dans SAPI/Windows (d'une incompatibilité quelque part), ce qui rend le code suivant élever le EZeroDivide exception:
procedure TForm1.FormClick(Sender: TObject);
var
SpVoice: variant;
begin
SpVoice := CreateOleObject('SAPI.SpVoice');
SpVoice.Speak('This is a text.');
end;
La solution, tel que présenté par la vidéo, est de modifier la FPU mot de contrôle:
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;
Et, en outre, si vous voulez jouer un son en mode asynchrone, vous devez vous assurer que le joueur n'est pas hors de portée!
Vous devez vous connecter pour publier un commentaire.
Vous trouverez peut-être intéressant de voir cette CodeRage 4 session sur "Discours Permettant d'Applications Delphi (zip)"
Vous obtiendrez le "how-to", vous êtes à la recherche pour...
(et je suppose que vous êtes sous Vista ou + comme la division par zéro n'est pas arrivé sur XP)
J'ai eu le même problème en Delphi XE2. Le
Set8087CW(SavedCW or $4)
solution présentée, la question n'a pas de travail pour moi. Il a simplement remplacé la division par zéro exception avec une autre exception de virgule flottante.Ce qui a fonctionné pour moi est: est-ce