Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Speech Recognition Manager /
Chapter 1 - Speech Recognition Manager / Using the Speech Recognition Manager


Handling Recognition Notifications

By default, a recognizer sends recognition notifications to your application's Apple event handler. If you wish, you can instruct a recognizer to send notifications to a speech recognition callback routine. See "Using Callback Routines" on page 1-28 for information on using callback routines.

IMPORTANT
You should use an Apple event handler to receive and process recognition notifications, unless your software is not an application (for example, a control panel or other software that cannot easily accept Apple events).
You need to specify to the recognizer what events you want to be notified about. By default, your application is notified when the recognizer has finished recognizing an utterance. You can also be notified when the recognizer begins the process of recognizing an utterance (that is, when the user begins speaking). You do this by setting the notification property of a recognizer, as shown in Listing 1-9.

Listing 1-9 Requesting notification of a recognition beginning

unsigned long myFlags;

myFlags = kSRNotifyRecognitionBeginning | kSRNotifyRecognitionDone;
myErr = SRSetProperty(gRecognizer, kSRNotificationParam, 
                                 &myFlags, sizeof(myFlags));
IMPORTANT
If you enable recognizer notification for the beginning of a recognition, then each time your application receives a recognition notification, you must call either SRContinueRecognition or SRCancelRecognition before speech recognition can continue. Otherwise, the recognizer will suspend its operations while waiting for you to call one of these functions.
In general, you need to receive kSRNotifyRecognitionBeginning notifications only if you want to update or modify the active language model according to context at the start of each utterance.

Using Apple Events

By default, the Speech Recognition Manager uses Apple events to inform your application of recognizer events. To receive notifications through Apple events, you need to install Apple event handlers for the events in the speech suite during application startup, as illustrated in Listing 1-10.

Listing 1-10 Installing an Apple event handler for speech events

myErr = AEInstallEventHandler(kAESpeechSuite, kAESpeechDetected,
            NewAEEventHandlerProc(MyHandleSpeechDetected), 0, FALSE);
if (!myErr) 
   myErr = AEInstallEventHandler(kAESpeechSuite, kAESpeechDone,
            NewAEEventHandlerProc(MyHandleSpeechDone), 0, FALSE);
Listing 1-11 illustrates how to respond to a recognizer notification of type kSRNotifyRecognitionDone sent to an Apple event handler.

Listing 1-11 Handling recognition done notifications with an Apple event handler

pascal OSErr MyHandleSpeechDone (AppleEvent *theAEevt, AppleEvent *reply, long refcon)
{
   long                 actualSize;
   DescType             actualType;
   OSErr                recStatus = 0, myErr = noErr
   SRRecognitionResult  recResult;
   SRRecognizer         myRec;

   /* Get recognition result status and recognizer. */
   myErr = AEGetParamPtr(theAEevt, keySRSpeechStatus, typeShortInteger,
            &actualType, (Ptr)&recStatus, sizeof(recStatus), &actualSize);
   if (!myErr)
      myErr = recStatus;

   if (!myErr) {
      myErr = AEGetParamPtr(theAEevt, keySRRecognizer, typeSRRecognizer, 
            &actualType, (Ptr)&myRec, sizeof(myRec), &actualSize);

      if (!myErr) {
         myErr = AEGetParamPtr(theAEevt, keySRSpeechResult, typeSRSpeechResult,
               &actualType, (Ptr)&recResult, sizeof(recResult), &actualSize);
         if (!myErr) {
            /* Process the recognition result here.*/
            MyProcessRecognitionResult(recResult);
            SRReleaseObject(recResult);
         }
      }
   }

   return(myErr);
}
Listing 1-12 illustrates how to respond to a recognition notification of type kSRNotifyRecognitionBeginning sent to an Apple event handler.

Listing 1-12 Handling recognition beginning notifications with an Apple event handler

pascal OSErr MyHandleSpeechDetected (AppleEvent *theAEevt, 
                                    AppleEvent *reply, long refcon)
{
   OSErr       myErr = noErr, recStatus = 0;
   DescType    actualType;
   long        actualSize;
   SRRecognizermyRec;

   /* Get status and recognizer. */
   myErr = AEGetParamPtr(theAEevt, keySRSpeechStatus, typeShortInteger,
               &actualType, (Ptr)&recStatus, sizeof(recStatus), &actualSize);
   if (!myErr)
      myErr = recStatus;

   if (!myErr) {
      myErr = AEGetParamPtr(theAEevt, keySRRecognizer, typeSRRecognizer, 
                  &actualType, (Ptr)&myRec, sizeof(myRec), &actualSize);
      if (!myErr) {
         /* The user has started speaking. We can adjust the language model */
         /* to reflect the current context. Then we must call either */
         /* SRContinueRecognition or SRCancelRecognition. */
         
         myErr = SRContinueRecognition(myRec);
      }
   }
   
   return(myErr);
}

Using Callback Routines

To instruct a recognizer to send notifications using a speech recognition callback routine instead of using Apple events, you set the kSRCallBackParam property of the recognizer to the address of a callback routine parameter structure, which specifies the address of your callback routine, as shown in Listing 1-13.

IMPORTANT
You should use an Apple event handler to receive and process recognition notifications, unless your software cannot easily accept Apple events.
Listing 1-13 Installing a speech recognition callback routine

pascal OSErr MyInstallSRCallBack (void)
{
   SRCallBackParam      myCallBackPB;
   
   myCallBackPB.callBack = NewSRCallBackProc(MySRCallBack);
   
   return SRSetProperty(gRecognizer, kSRCallBackParam, 
                        &myCallBackPB, sizeof(myCallBackPB));
}
Note
See page 1-51 for details on the callback routine parameter structure (of type SRCallBackParam).
You can remove a speech recognition callback routine, as shown in Listing 1-14.

Listing 1-14 Removing a speech recognition callback routine

pascal void MyRemoveSRCallBack (void)
{
   SRCallBackParam      myCallBackPB;
   SRCallBackUPP        mySavedCallBack;
   Size                 myLen;
   OSErr                myErr = noErr;
   
   myLen = sizeof(myCallBackPB);
   myErr = SRGetProperty(gRecognizer, kSRCallBackParam, 
                        &myCallBackPB, &myLen);
   if (myErr == noErr) {
      if (myCallBackPB.callBack != nil) {
         mySavedCallBack = myCallBackPB.callBack;
         myCallBackPB.callBack = nil;
         myErr = SRSetProperty(gRecognizer, kSRCallBackParam, 
                        &myCallBackPB, sizeof(myCallBackPB));
         DisposeRoutineDescriptor(mySavedCallBack);
      }
   }
}
IMPORTANT
You should not call any Speech Recognition Manager routines other than SRContinueRecognition or SRCancelRecognition in your speech recognition callback routine. Usually, your callback routine should simply queue the notification it receives for later processing by your software (for instance, when you receive background processing time).
You can queue the notification by setting a global flag that indicates the recognition result to process, as shown in Listing 1-15.

Listing 1-15 Handling notifications with a callback routine

SRRecognitionResultgLastRecResult;/* last rec result received */

pascal void MySRCallBack (SRCallBackStruct *param)
{
   OSErr             myErr = param->status;
   
   if (!myErr) {
      /* Handle recognition beginning event. */
      /* Here we just continue speech recognition. */
      if ((param->what) & kSRNotifyRecognitionBeginning) {
         SRRecognizermyRec = (SRRecognizer) (param->instance);

         myErr = SRContinueRecognition(myRec);
   }
      /* Handle recognition done event. */
      /* Here we save the rec result in gLastRecResult. */
      /* At idle time in our event loop, if gLastRecResult != NULL, */
      /* we call MyHandleRecognitionResult(gLastRecResult) */
   else if (param->what & kSRNotifyRecognitionDone) {
      SRRecognitionResult myResult = 
                        (SRRecognitionResult) (param->message);
      if (myResult)
         gLastRecResult = myResult;
         /* Note that we might get more than one result  */
         /* before we get to our idle check,  */
         /* so we should really be putting this in a queue. */
      }
   }
}
The MySRCallBack function simply determines what event prompted the recognition notification and sets a global flag to signal the application to do the correct thing (for example, process the recognition result). Your application needs to examine that flag periodically to determine whether to handle the result. Listing 1-16 shows an example of a routine that does this.

Listing 1-16 Checking whether a recognition result needs processing

pascal void MyIdleCheckForSpeechResult (void)
{
   if (gLastRecResult != NULL)
      MyProcessRecognitionResult(gLastRecResult);
   
   gLastRecResult = NULL;
}
If a recognition result is pending, the application calls its routine to handle recognition results, MyProcessRecognitionResult (defined in the next section).

IMPORTANT
See "Speech Recognition Callback Routines" on page 1-85 for a complete description of the limitations of using callback routines.

Previous Book Contents Book Index Next

© Apple Computer, Inc.
22 JAN 1997