Пример #1
0
Boolean AddCommands( SRRecognizer inSpeechRecognizer, SRLanguageModel inCommandsLangaugeModel, CFArrayRef inCommandNamesArray )
{

    // Dictionary keys for Commands Data property list
    #define	kCommandsDataPlacementHintKey			"PlacementHint"			// value type is: CFNumberRef
        #define	kPlacementHintWhereverNumValue			0
        #define	kPlacementHintProcessNumValue			1					// you must also provide the PSN using kCommandsDataProcessPSNHighKey & kCommandsDataProcessPSNLowKey
        #define	kPlacementHintFirstNumValue				2
        #define	kPlacementHintMiddleNumValue			3
        #define	kPlacementHintLastNumValue				4
    #define	kCommandsDataProcessPSNHighKey			"ProcessPSNHigh"		// value type is: CFNumberRef
    #define	kCommandsDataProcessPSNLowKey			"ProcessPSNLow"			// value type is: CFNumberRef
    #define	kCommandsDataDisplayOrderKey				"DisplayOrder"			// value type is: CFNumberRef  - the order in which recognizers from the same client process should be displayed.
    #define	kCommandsDataCmdInfoArrayKey				"CommandInfoArray"		// value type is: CFArrayRef of CFDictionaryRef values
        #define	kCommandInfoNameKey						"Text"
        #define	kCommandInfoChildrenKey					"Children"

    Boolean	successfullyAddCommands = false;
    
    if (inCommandNamesArray) {
    
        CFIndex	numOfCommands = CFArrayGetCount( inCommandNamesArray );
        CFMutableArrayRef	theSectionArray = CFArrayCreateMutable( NULL, 0, &kCFTypeArrayCallBacks );
        
        // Erase any existing commands in the language model before we begin adding the given list of commands
        if (SREmptyLanguageObject( inCommandsLangaugeModel ) == noErr && theSectionArray) {
        
            CFIndex	i;
            char 	theCSringBuffer[100];

            successfullyAddCommands = true;
            for (i = 0; i < numOfCommands; i++) {
               
                 CFStringRef	theCommandName = CFArrayGetValueAtIndex(inCommandNamesArray, i);
                if (theCommandName && CFStringGetCString( theCommandName, theCSringBuffer, 100, kCFStringEncodingMacRoman )) {
                    
                    if (SRAddText( inCommandsLangaugeModel, theCSringBuffer, strlen(theCSringBuffer), i) == noErr) {
    
                        CFStringRef 	keys[1];
                        CFTypeRef		values[1];
                        CFDictionaryRef theItemDict;
                        
                        keys[0] 	= CFSTR( kCommandInfoNameKey );
                        values[0] 	= theCommandName;
                        
                        // Make CDDictionary our keys and values.
                        theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                        
                        // Add to command array
                        if (theItemDict) {
                            CFArrayAppendValue( theSectionArray, theItemDict );
                            CFRelease( theItemDict );  // We release our hold on the dictionary object and let the array own it now.
                        }
                        else
                            successfullyAddCommands = false;
                    }
                    else
                        successfullyAddCommands = false;
                    
                    if (! successfullyAddCommands)
                        break;
                }
            }
    
            //
            // Create the XML data that contains the commands to display and give this data to the
            // recognizer object to display in the Speech Commands window.
            //
            {
                CFIndex				numOfParams = 4;
                CFStringRef 		keys[numOfParams];
                CFTypeRef			values[numOfParams];
                CFDictionaryRef 	theItemDict;
                SInt32				placementHint = 1;	// 1 = show only when this app is front process
                ProcessSerialNumber	thisAppsPSN;
                
                thisAppsPSN.highLongOfPSN = 0;
                thisAppsPSN.lowLongOfPSN = 0;
        
                GetCurrentProcess( &thisAppsPSN );
            
                keys[0] 	= CFSTR( kCommandsDataPlacementHintKey );
                keys[1] 	= CFSTR( kCommandsDataCmdInfoArrayKey );
                keys[2] 	= CFSTR( kCommandsDataProcessPSNHighKey );
                keys[3] 	= CFSTR( kCommandsDataProcessPSNLowKey );
                values[0] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &placementHint);
                values[1] 	= theSectionArray;
                values[2] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.highLongOfPSN));
                values[3] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.lowLongOfPSN));
                    
                // Make CDDictionary of our keys and values.
                theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, numOfParams, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                if (theItemDict) {
                
                    // Convert CFDictionary object to XML representation
                    CFDataRef dictData = CFPropertyListCreateXMLData(NULL, theItemDict);
                    if (dictData) {

                    	// Set command list in our SRRecognizer object, causing the Speech Commands window to update.
                        (void)SRSetProperty (inSpeechRecognizer, 'cdpl', CFDataGetBytePtr(dictData), CFDataGetLength(dictData));
                        CFRelease( dictData );
                    }
                }
                
                // Release our hold on the dictionary object and let the array own it now.
                if (theItemDict)
                    CFRelease( theItemDict );
                
                // Release our values
                if (values[0])
                    CFRelease( values[0] );
                
                if (values[2])
                    CFRelease( values[2] );
                    
                if (values[3])
                    CFRelease( values[3] );
                    
                CFRelease( theSectionArray );
            }
        }

    }
    
    return successfullyAddCommands;
}
Пример #2
0
Boolean AddCommands( SRRecognizer inSpeechRecognizer, SRLanguageModel inCommandsLangaugeModel, CFArrayRef inCommandNamesArray )
{

    // Dictionary keys for Commands Data property list
    #define	kCommandsDataPlacementHintKey			"PlacementHint"			// value type is: CFNumberRef
        #define	kPlacementHintWhereverNumValue			0
        #define	kPlacementHintProcessNumValue			1					// you must also provide the PSN using kCommandsDataProcessPSNHighKey & kCommandsDataProcessPSNLowKey
        #define	kPlacementHintFirstNumValue				2
        #define	kPlacementHintMiddleNumValue			3
        #define	kPlacementHintLastNumValue				4
    #define	kCommandsDataProcessPSNHighKey			"ProcessPSNHigh"		// value type is: CFNumberRef
    #define	kCommandsDataProcessPSNLowKey			"ProcessPSNLow"			// value type is: CFNumberRef
    #define	kCommandsDataDisplayOrderKey				"DisplayOrder"			// value type is: CFNumberRef  - the order in which recognizers from the same client process should be displayed.
    #define	kCommandsDataCmdInfoArrayKey				"CommandInfoArray"		// value type is: CFArrayRef of CFDictionaryRef values
        #define	kCommandInfoNameKey						"Text"
        #define	kCommandInfoChildrenKey					"Children"

    Boolean	successfullyAddCommands = false;
    
    if (inCommandNamesArray) {
    
        CFIndex	numOfCommands = CFArrayGetCount( inCommandNamesArray );
        CFMutableArrayRef	theSectionArray = CFArrayCreateMutable( NULL, 0, &kCFTypeArrayCallBacks );
        
        // Erase any existing commands in the language model before we begin adding the given list of commands
        if (SREmptyLanguageObject( inCommandsLangaugeModel ) == noErr && theSectionArray) {
        
            CFIndex	i;
            char 	theCSringBuffer[100];

            successfullyAddCommands = true;
            for (i = 0; i < numOfCommands; i++) {
               
                 CFStringRef	theCommandName = CFArrayGetValueAtIndex(inCommandNamesArray, i);
                if (theCommandName && CFStringGetCString( theCommandName, theCSringBuffer, 100, kCFStringEncodingMacRoman )) {
                    
// Conditionalized just to remove compiler warnings.
#if __LP64__
                    if (SRAddText( inCommandsLangaugeModel, theCSringBuffer, strlen(theCSringBuffer), (void *)i) == noErr) {
#else
                    if (SRAddText( inCommandsLangaugeModel, theCSringBuffer, strlen(theCSringBuffer), i) == noErr) {
#endif    
                        CFStringRef 	keys[1];
                        CFTypeRef		values[1];
                        CFDictionaryRef theItemDict;
                        
                        keys[0] 	= CFSTR( kCommandInfoNameKey );
                        values[0] 	= theCommandName;
                        
                        // Make CDDictionary our keys and values.
                        theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                        
                        // Add to command array
                        if (theItemDict) {
                            CFArrayAppendValue( theSectionArray, theItemDict );
                            CFRelease( theItemDict );  // We release our hold on the dictionary object and let the array own it now.
                        }
                        else
                            successfullyAddCommands = false;
                    }
                    else
                        successfullyAddCommands = false;
                    
                    if (! successfullyAddCommands)
                        break;
                }
            }
    
            //
            // Create the XML data that contains the commands to display and give this data to the
            // recognizer object to display in the Speech Commands window.
            //
            {
                CFIndex				numOfParams = 4;
                CFStringRef 		keys[numOfParams];
                CFTypeRef			values[numOfParams];
                CFDictionaryRef 	theItemDict;
                SInt32				placementHint = 1;	// 1 = show only when this app is front process
                ProcessSerialNumber	thisAppsPSN;
                
                thisAppsPSN.highLongOfPSN = 0;
                thisAppsPSN.lowLongOfPSN = 0;
        
                GetCurrentProcess( &thisAppsPSN );
            
                keys[0] 	= CFSTR( kCommandsDataPlacementHintKey );
                keys[1] 	= CFSTR( kCommandsDataCmdInfoArrayKey );
                keys[2] 	= CFSTR( kCommandsDataProcessPSNHighKey );
                keys[3] 	= CFSTR( kCommandsDataProcessPSNLowKey );
                values[0] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &placementHint);
                values[1] 	= theSectionArray;
                values[2] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.highLongOfPSN));
                values[3] 	= CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.lowLongOfPSN));
                    
                // Make CDDictionary of our keys and values.
                theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, numOfParams, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                if (theItemDict) {
                
                    // Convert CFDictionary object to XML representation
                    CFDataRef dictData = CFPropertyListCreateXMLData(NULL, theItemDict);
                    if (dictData) {

                    	// Set command list in our SRRecognizer object, causing the Speech Commands window to update.
                        (void)SRSetProperty (inSpeechRecognizer, 'cdpl', CFDataGetBytePtr(dictData), CFDataGetLength(dictData));
                        CFRelease( dictData );
                    }
                }
                
                // Release our hold on the dictionary object and let the array own it now.
                if (theItemDict)
                    CFRelease( theItemDict );
                
                // Release our values
                if (values[0])
                    CFRelease( values[0] );
                
                if (values[2])
                    CFRelease( values[2] );
                    
                if (values[3])
                    CFRelease( values[3] );
                    
                CFRelease( theSectionArray );
            }
        }

    }
    
    return successfullyAddCommands;
}


/*
    ConvertAppleEventResultIntoCommandID
    
    This routine converts the Apple event data received from a speech done (kAESpeechSuite, kAESpeechDone) 
    Apple event into a command ID when using the AddCommands routine to add your commands to the top-level
    language model.
    
    This routine returns true if the spoken utterance was recognized as a valid command.
*/

Boolean ConvertAppleEventResultIntoCommandID( const AppleEvent *inAppleEvent, long * outCommandID )
{
    Boolean			successfullyFound = false;
    Size			actualSize;
    DescType		actualType;
    OSErr			recStatus = noErr;
    
    //	Get recognition status from AE, and check that it is equal to 0.
    if (AEGetParamPtr( inAppleEvent, keySRSpeechStatus, typeSInt16, &actualType, (Ptr)&recStatus, sizeof(recStatus), &actualSize) == noErr && recStatus == noErr) {
    
        // Get recognition result from AE, and continue if not NULL.
        SRRecognitionResult recResult = NULL;
        if (AEGetParamPtr( inAppleEvent, keySRSpeechResult, typeSRSpeechResult, &actualType, (Ptr)&recResult, sizeof(recResult), &actualSize) == noErr && recResult) {
    
            // Get language model result from recognition result
            Size				theLen = sizeof(SRLanguageModel);
            SRLanguageModel		resultLanguageModel	= 0;  
            if (SRGetProperty( recResult, kSRLanguageModelFormat, &resultLanguageModel, &theLen ) == noErr) {
            
                // Get the recognized command object from the language model
                // Since there will only be one object in the langauge model, we just grab the first one.
                SRLanguageObject	resultingCommandObj = 0;
                if (SRGetIndexedItem( resultLanguageModel, &resultingCommandObj, 0 ) == noErr) {
                
                    // Get the command ID from the refCon property of the recognized command object.
                    theLen = sizeof(long);
                    if (SRGetProperty( resultingCommandObj, kSRRefCon, outCommandID, &theLen ) == noErr)
                        successfullyFound = true;
                }
            }
        }
    }
    
    return successfullyFound;
}