Antes que nada: esto no es un duplicado de Delphi and SAPI. Tengo un problema específico con el tema "SAPI en Delphi".Delphi SAPI Text-To-Speech
He utilizado la excelente guía Import Type-Library en Delphi 2009 para obtener un componente TSpVoice en la paleta de componentes. Esto funciona genial Con
var
SpVoice: TSpVoice;
Puedo escribir
SpVoice.Speak('This is an example.', 1);
para obtener salida de audio asíncrono.
Primera pregunta
Según la documentación, que sería capaz de escribir
SpVoice.Speak('This is an example.', 0);
para obtener salida de audio sincrónica, pero en lugar de eso obtener una excepción EZeroDivide. ¿Porque eso?
Segunda pregunta
Pero lo más importante, me gustaría ser capaz de crear el objeto SpVoice dinámicamente (creo que esto es llamado a "late-bind" el objeto SpVoice), en parte debido a que sólo una fracción muy pequeña de todas las sesiones de mi aplicación lo usará, y en parte porque no quiero suponer la existencia del servidor SAPI en el sistema del usuario final.
Con este fin, he intentado
procedure TForm1.FormClick(Sender: TObject);
var
SpVoice: Variant;
begin
SpVoice := CreateOleObject('SAPI.SpVoice');
SpVoice.Speak('this is a test', 0);
end;
que aparentemente no hace nada en absoluto! (Sustitución de la 0 a 1 me da la excepción EZeroDivide.)
Negación
Soy bastante nuevo en la automatización COM/OLE. Lo siento por cualquier ignorancia o estupidez mostrado por mí en este post ...
actualización
Para el beneficio de todos encontrarse con el mismo problema que yo, el video por François explicó que hay un error en el SAPI/Windows (alguna incompatibilidad alguna parte), lo que hace que el siguiente código elevar la excepción EZeroDivide:
procedure TForm1.FormClick(Sender: TObject);
var
SpVoice: variant;
begin
SpVoice := CreateOleObject('SAPI.SpVoice');
SpVoice.Speak('This is a text.');
end;
la solución, según lo presentado por el video, es alterar la palabra de control FPU:
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;
Y, además, si desea reproducir un sonido de forma asíncrona, ¡entonces debe asegurarse de que el reproductor no se salga de alcance!
Ah, muchas gracias! Entonces, ¡no era solo que yo fuera estúpido! –
BTW: ¡No dude en eliminar el signo de interrogación al lado de su nombre si desea atribuirse el mérito del video! :) –