Difference between revisions of "SAPI"

From Free Pascal wiki
Jump to navigationJump to search
m (Link to accessibility OSX VoiceOver)
Line 9: Line 9:
 
<syntaxhighlight>
 
<syntaxhighlight>
 
uses
 
uses
//... to do: what to add here?? Ludo's OLE/ActiveX library probably...
+
  ...,comobj;
 
var
 
var
 
   SavedCW: Word;
 
   SavedCW: Word;
Line 15: Line 15:
 
begin
 
begin
 
   SpVoice := CreateOleObject('SAPI.SpVoice');
 
   SpVoice := CreateOleObject('SAPI.SpVoice');
   // Change FPU mask to avoid SIGSEGV 
+
   // Change FPU interrupt mask to avoid SIGFPE exceptions
 
   SavedCW := Get8087CW;
 
   SavedCW := Get8087CW;
 
   try
 
   try
Line 24: Line 24:
 
     Set8087CW(SavedCW);
 
     Set8087CW(SavedCW);
 
   end;
 
   end;
  //todo: clean up object
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
For the options available with SpVoice.Speak and other SpVoice methods see http://msdn.microsoft.com/en-us/library/ms723609(v=vs.85).aspx.
 +
: '''WARNING''' The Ole object created in above snippet will be destroyed automatically when the SpVoice variant goes out of scope. For larger texts the use of the asynchronous mode allows to keep your application reactive while speak is running. In that case it is especially important to control carefully the lifetime of the object and store it in a global or class variable. Destroying the object while speak is still running can cause crashes.
 +
Changing the FPU interrupt mask can be done at any moment before loading the ole object and if your application is not using any floating point arithmetic there is no need to reset the FPU interrupt mask to its original value.
  
 
== Linux/Unix alternatives ==
 
== Linux/Unix alternatives ==

Revision as of 13:42, 15 August 2012

What is it

SAPI stands for Speech Application Programming Interface, a Microsoft Windows API used to perform text-to-speech (TTS).

Use with FreePascal

Lazarus/FreePascal can use this interface to perform TTS. Source: forum post: [1]

On Windows Vista and above, you will run in trouble with the FPU interrupt mask (see [2]). The code dealing with SavedCW is meant to work around this.

uses
  ...,comobj;
var
  SavedCW: Word;
  SpVoice: Variant;
begin
  SpVoice := CreateOleObject('SAPI.SpVoice');
  // Change FPU interrupt mask to avoid SIGFPE exceptions
  SavedCW := Get8087CW;
  try
    Set8087CW(SavedCW or $4);
    SpVoice.Speak('hi', 0);
  finally
    // Restore FPU mask
    Set8087CW(SavedCW);
  end;

For the options available with SpVoice.Speak and other SpVoice methods see http://msdn.microsoft.com/en-us/library/ms723609(v=vs.85).aspx.

WARNING The Ole object created in above snippet will be destroyed automatically when the SpVoice variant goes out of scope. For larger texts the use of the asynchronous mode allows to keep your application reactive while speak is running. In that case it is especially important to control carefully the lifetime of the object and store it in a global or class variable. Destroying the object while speak is still running can cause crashes.

Changing the FPU interrupt mask can be done at any moment before loading the ole object and if your application is not using any floating point arithmetic there is no need to reset the FPU interrupt mask to its original value.

Linux/Unix alternatives

On Linux/Unix, there are some command line Text To Speech engines, that may also offer access via APIs. An example is the festival engine.

OSX alternatives

OSX has system wide text to speech functionality built in: VoiceOver. See LCL_Accessibility#Mac_OS_X_VoiceOver