Previous Book Contents Book Index Next

Inside Macintosh: Sound /
Chapter 4 - Speech Manager / Using the Speech Manager


Legacy Documentclose button

Important: Inside Macintosh: Sound is deprecated as of Mac OS X v10.5. For new audio development in Mac OS X, use Core Audio. See the Audio page in the ADC Reference Library.

Implementing Callback Procedures

The Speech Manager makes it easy for you to synchronize other activities to speech generation by allowing you to install various types of callback procedures on a speech channel. A callback procedure is a procedure that executes whenever a certain type of event is about to occur or has occurred. For example, you might use a word callback procedure to ensure that whenever the Speech Manager is about to speak a word, the word is visible onscreen. Callback procedures also allow you to synchronize more mundane activities with the Speech Manager; for example, you might need to know when you can dispose of a certain text buffer that you had asked the Speech Manager to speak. This section provides an overview of the different callback procedures that you can define.

The soTextDoneCallBack and soSpeechDoneCallBack speech information selectors allow you to designate text-done and speech-done callback procedures. A text-done callback procedure executes whenever the Speech Manager finishes processing a buffer of text to be spoken. This procedure usually executes before the Speech Manager has finished generating speech from the text and indeed often before it has started. The text-done callback procedure provides a mechanism that allows you to specify to the Speech Manager an additional buffer of text to be spoken, so that speech is generated continuously. Once your text-done callback procedure executes, you can release the memory occupied by the text buffer processed. A speech-done callback procedure does not execute until after the Speech Manager has completed generating speech from a buffer of text.

If your application uses or supports embedded speech commands, it may need to use the soSyncCallBack and soErrorCallBack speech information selectors to designate a synchronization callback procedure or an error callback procedure. A synchronization callback procedure executes whenever the Speech Manager encounters a synchronization command embedded within a text buffer to be spoken. An error callback procedure executes whenever the Speech Manager encounters an error when attempting to process an embedded speech command. The Speech Manager passes information about the synchronization message or type of error to your callback procedure. If your application does not use synchronization or error callback procedures, it can obtain information about synchronization or error messages by continually polling the speech channel by using the GetSpeechInfo function with the soErrors or soRecentSync selectors.

The soPhonemeCallBack and soWordCallBack speech information selectors allow you to designate a phoneme callback procedure and a word callback procedure, respectively. A phoneme callback procedure executes whenever a phoneme is about to be spoken on a speech channel. A word callback procedure executes whenever a word is about to be spoken on a speech channel.

Since callback procedures execute at interrupt time they face several restrictions, as discussed in detail in Inside Macintosh: Processes. Most significantly, your callback procedure must not allocate or move memory or call any Toolbox or Operating System routine that might do so. Thus, typically a callback procedure simply sets a flag variable; for example, a phoneme callback procedure might change a variable that indicates which phoneme is being spoken. Your application can then poll this flag variable each time through its main event loop and perform whatever activity is desired if it finds that the flag variable has changed. Remember to design callback procedures to execute quickly.

Because they execute at interrupt time, callback procedures also cannot access application global variables unless the A5 register contains the value of the application's A5, as discussed in Inside Macintosh: Memory. Fortunately, the Speech Manager provides a mechanism that makes it easy to ensure that A5 is set correctly. Your application can call the SetSpeechInfo function with the soCurrentA5 selector to pass the application's A5 in the speechInfo parameter to the Speech Manager. The Speech Manager will then set the A5 register to the passed value whenever it executes an application-defined callback procedure for that speech channel.

Sometimes your application might wish to provide a callback procedure with additional information beyond that which can be provided by examining application global variables. For example, a callback procedure might need to know from which document speech is being generated. Your application can use the SetSpeechInfo function with the soRefCon selector to specify a 4-byte reference constant value--for example, a handle to a document record--that the Speech Manager passes to all callback procedures on a particular speech channel. Your application can use the same callback procedure on multiple speech channels, for each of which the Speech Manager can pass a different value to the callback procedure. Thus, as long as your application never uses a single speech channel to generate speech on multiple documents simultaneously, it can use the reference constant value mechanism to pass document-specific information to a callback procedure. Typically, you use the reference constant to contain a pointer or handle to more extensive information that the callback procedure would require.

Listing 4-6 shows how you can indicate to the Speech Manager both the value to which it should set the A5 register when it executes a callback procedure on a particular speech channel and the reference constant value to pass to that callback procedure.

Listing 4-6 Setting up a speech channel for callbacks

FUNCTION MySetupCallbacks (chan: SpeechChannel; refCon: LongInt): OSErr;
VAR
   myA5:       LongInt;                {application's A5}
   myErr:      OSErr;
BEGIN
   myA5 := SetCurrentA5;               {get application's A5}

   {Pass A5 value to speech channel.}
   myErr := SetSpeechInfo(chan, soCurrentA5, Ptr(myA5));
   IF myErr = noErr THEN               {set the reference constant}
      myErr := SetSpeechInfo(chan, soRefCon, Ptr(refCon));

   MySetupCallbacks := myErr;
END;
The MySetupCallbacks function defined in Listing 4-6 uses the SetSpeechInfo function with both the soCurrentA5 and the soRefCon selectors to prepare a specific speech channel for callbacks. Note that your application can call MySetupCallbacks as many times as desired for any particular speech channel; you might do this if you want to change the reference constant value to be passed to the speech channel.

Unlike other selectors, the soCurrentA5 and soRefCon selectors do not require that you pass a pointer to the information you are specifying in the speechInfo parameter. Because an application's A5 value and a speech channel's reference constant value are always each 4 bytes long (the same size as the speechInfo parameter), your application passes these values directly, casting them to pointer values.

After your application sets up the A5 register and defines a reference constant value, it can install the appropriate type or types of callback procedure. Listing 4-7 shows how you might install a word callback procedure.

Listing 4-7 Installing a word callback procedure

PROCEDURE MyInstallWordCallback (chan: SpeechChannel; callbackProc: ProcPtr;
                                    refCon: LongInt);
VAR
   myErr:      OSErr;
BEGIN
   myErr := MySetupCallbacks(chan,  refCon);    {set up callbacks}
   myErr := SetSpeechInfo(chan, soWordCallBack, callbackProc);
   IF myErr <> noErr THEN
      DoError(myErr);                           {respond to an error}
END;
The MyInstallWordCallback procedure defined in Listing 4-7 first prepares for callbacks by calling the MySetupCallbacks function defined in Listing 4-6 for the speech channel and reference constant value specified by the chan and refCon parameters, respectively. Then it installs the callback procedure specified by the callbackProc parameter by using the SetSpeechInfo function with the soWordCallBack speech information selector. If, for example, you want to pass to your word callback procedure a pointer to the window containing the document being used for speech generation, you might call the MyInstallWordCallback procedure like this:

MyInstallWordCallback(mySpeechChan, @MyWordCallBack, LongInt(myWindow));
Listing 4-8 defines a simple word callback procedure.

Listing 4-8 A typical word callback procedure

PROCEDURE MyWordCallback (chan: SpeechChannel; refCon: LongInt;
                           wordPos: LongInt; wordLen: Integer);
BEGIN
   gWindowBeingRead := WindowPtr(refCon);
   gWordPos := wordPos;
   gWordLen := wordLen;
END;
WARNING
Callback procedures are called at interrupt time and therefore must not attempt to allocate, move, or dispose of memory; dereference an unlocked handle; or call other routines that do so. Also, a callback procedure is a Pascal procedure and must preserve all registers other than A0-A1 and D0-D2.
Because of the restrictions on callback procedures, a typical callback procedure usually just sets global flag variables based on the information passed to it. In Listing 4-8, the callback procedure copies information from the refCon, wordPos, and wordLen parameters to the three global variables gWindowBeingRead, gWordPos, and gWordLen. You can then call a routine to check the values of these global variables once each time through your application's event loop and respond appropriately if the gWindowBeingRead global variable is not NIL. (Your application would have to initialize the variable to NIL.) For example, the routine might ensure that the word about to be spoken is visible onscreen and scroll the document appropriately if it is not.

Although they have different uses, speech-done callback procedures, synchronization callback procedures, error callback procedures, and phoneme callback procedures are typically defined in ways similar to that of the word callback procedure in Listing 4-8. See "Application-Defined Routines" beginning on page 4-82 for complete information on callback routines.

Text-done callback procedures are usually more complex than the other types. You can use a text-done callback procedure simply to determine when the Speech Manager has completed processing a buffer of input text. The callback procedure can just set a global flag variable that is inspected once each time through the application's main event loop; when the flag variable indicates that the input buffer processing is complete, you can dispose of the input buffer.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
2 JUL 1996