Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Language.c
/* |
File: Language.c |
Contains: |
Written by: |
Copyright: Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/2/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#ifndef __LANGUAGE__ |
#include "Language.h" |
#endif |
#include <Errors.h> |
OSErr MakeNewLanguage (SpeechInfoPtr theSpeechInfo) |
{ |
OSErr theErr = noErr; |
/* Make language models */ |
theErr = ReadInLanguages (theSpeechInfo); |
/* Use this LM in recognition */ |
if (theErr == noErr) { |
theErr = SRSetLanguageModel (theSpeechInfo->theRecognizer, theSpeechInfo->languages->theLanguage); |
} |
return theErr; |
} |
OSErr ReadInLanguages (SpeechInfoPtr theSpeechInfo) |
{ |
LanguageModelListPtr currentLang = nil; |
TREEResourcePtr TREEResPtr = nil; |
short numLanguages = 0, |
onlySubPath = false, |
i; |
OSErr theErr = noErr; |
numLanguages = Count1Resources (kTREEType); |
theErr = ResError (); |
theSpeechInfo->languages = (LanguageModelListPtr)NewPtr (sizeof (LanguageModelList)); |
theSpeechInfo->languages->nextLanguage = nil; |
currentLang = theSpeechInfo->languages; |
for (i = 0; i < numLanguages; i++) { |
theErr = GetTREERes (&TREEResPtr, kBaseResID + i, 1, &onlySubPath); |
DisposePtr ((Ptr)TREEResPtr); |
if (onlySubPath == false) { |
theErr = AddStringsToLanguage (theSpeechInfo, currentLang, kBaseResID + i); |
if (i+1 < numLanguages) { |
currentLang->nextLanguage = (LanguageModelListPtr)NewPtr (sizeof (LanguageModelList)); |
currentLang = currentLang->nextLanguage; |
} |
else { |
currentLang->nextLanguage = nil; |
} |
currentLang->resID = kBaseResID + i; |
} |
} |
return theErr; |
} |
OSErr AddStringsToLanguage (SpeechInfoPtr theSpeechInfo, LanguageModelListPtr currentLang, short resID) |
{ |
SRLanguageModel newModel; |
SRPath beginningOfPath, |
restOfPath; |
Str63 phraseString; |
OSType type = 0; |
TREEResourcePtr TREEResPtr = nil; |
CommandPtr theCommand = nil; |
long refCon = 0, |
flags = 0, |
ID = 0; |
short j = 1, |
onlySubPath = false; |
OSErr theErr = noErr; |
Boolean done = false; |
theErr = SRNewLanguageModel (theSpeechInfo->recogSystem, &newModel, nil, 0); |
refCon = resID; |
theErr = SRSetProperty (newModel, kSRRefCon, &refCon, sizeof (refCon)); |
/* add each phrase to LM */ |
refCon = refCon << 16; |
do { |
theErr = GetTREERes (&TREEResPtr, resID, j, &onlySubPath); |
if (theErr == noErr) { |
theErr = GetFlagsFromTREE (&flags, TREEResPtr); |
} |
if (theErr == noErr && flags == 0) { |
/* Read resource to get top level names to be recognized */ |
theErr = GetStringFromTREE (phraseString, TREEResPtr); |
if (phraseString[0] == 0) { |
theErr = noErr; |
done = true; /* Found the last name */ |
} |
if (done == false) { |
theErr = RegisterCommand (TREEResPtr, &theCommand); |
theErr = SRAddText (newModel, phraseString+1, phraseString[0], (long)theCommand); |
} |
} |
else if (theErr == noErr && flags == 1) { |
/* This word is the beginning of a path, i.e. "lights X" where X can |
be on, off, dim, etc. */ |
theErr = GetTypeFromTREE (&type, TREEResPtr); |
if (theErr == noErr && type == kTREEType) { |
theErr = GetIDFromTREE (&ID, TREEResPtr); |
} |
if (theErr == noErr) { |
theErr = SRNewPath (theSpeechInfo->recogSystem, &beginningOfPath); |
if (theErr == noErr) { |
theErr = GetStringFromTREE (phraseString, TREEResPtr); |
if (phraseString[0] == 0) { |
theErr = noErr; |
done = true; /* Found the last name */ |
} |
if (done == false) { |
theErr = SRAddText (beginningOfPath, phraseString+1, phraseString[0], 0); |
if (theErr == noErr) { |
theErr = GetTREERes (&TREEResPtr, ID, 1, &onlySubPath); |
} |
if (theErr == noErr) { |
theErr = AddStringsToLanguage (theSpeechInfo, currentLang, ID); |
} |
if (theErr == noErr) { |
theErr = SRNewPath (theSpeechInfo->recogSystem, &restOfPath); |
if (theErr == noErr) { |
theErr = SRAddLanguageObject (restOfPath, currentLang->theLanguage); |
} |
if (theErr == noErr) { |
theErr = SRAddLanguageObject (beginningOfPath, restOfPath); |
} |
if (theErr == noErr) { |
theErr = SRAddLanguageObject (newModel, beginningOfPath); |
} |
} |
} |
} |
} |
} |
j++; |
} while (theErr == noErr && done == false); |
if (theErr == resNotFound) { |
theErr = noErr; |
} |
if (theErr != noErr) { /* release newly created LM if an error occured while adding phrases */ |
SRReleaseObject (newModel); |
} |
else { /* return new LM */ |
//We don't release the language models because we will be switching between them later |
currentLang->theLanguage = newModel; |
} |
return theErr; |
} |
OSErr GetTREERes (TREEResourcePtr *theTREEResPtr, short resID, short index, short *onlySubPath) |
{ |
TREEResourcePtr TREEResPtr = nil; |
Handle TREEHandle = nil; |
long offset = 0; |
OSErr theErr = noErr; |
short itemCount = 0, |
i; |
TREEHandle = Get1Resource (kTREEType, resID); |
theErr = ResError (); |
if (TREEHandle != nil && theErr == noErr) { |
*onlySubPath = ((short *)*TREEHandle)[0]; |
itemCount = ((short *)*TREEHandle)[1]; |
if (index > itemCount || index < 1) { |
theErr = resNotFound; |
} |
else { |
offset = 4; /* account for one time bytes at start of resource */ |
for (i = 0; i < index; i++) { |
TREEResPtr = (TREEResourcePtr)&(*TREEHandle)[offset]; |
offset += 12; /* account for flags, type, and ID */ |
/* length of string (plus size byte), rounded to a quad byte length */ |
offset += (((TREEResPtr->name[0] + 1) + 3) & ~3); |
} |
*theTREEResPtr = (TREEResourcePtr)NewPtr (sizeof (TREEResource) + TREEResPtr->name[0]); |
if (*theTREEResPtr != nil && MemError () == noErr) { |
(*theTREEResPtr)->flags = TREEResPtr->flags; |
(*theTREEResPtr)->type = TREEResPtr->type; |
(*theTREEResPtr)->ID = TREEResPtr->ID; |
for (i = 0; i < TREEResPtr->name[0] + 1; i++) { |
(*theTREEResPtr)->name[i] = TREEResPtr->name[i]; |
} |
} |
ReleaseResource (TREEHandle); |
theErr = ResError (); |
} |
} |
return theErr; |
} |
OSErr RegisterCommand (TREEResourcePtr theTREEResPtr, CommandPtr *theCommand) |
{ |
OSErr theErr = noErr; |
*theCommand = (CommandPtr)NewPtr (sizeof(Command)); |
theErr = GetFlagsFromTREE (&(*theCommand)->flags, theTREEResPtr); |
theErr = GetTypeFromTREE (&(*theCommand)->type, theTREEResPtr); |
theErr = GetIDFromTREE (&(*theCommand)->ID, theTREEResPtr); |
return theErr; |
} |
OSErr GetFlagsFromTREE (long *theFlags, TREEResourcePtr theTREEResPtr) |
{ |
OSErr theErr = noErr; |
if (theTREEResPtr != nil) { |
*theFlags = theTREEResPtr->flags; |
} |
else { |
theErr = kNilPtrErr; |
} |
return theErr; |
} |
OSErr GetTypeFromTREE (OSType *theType, TREEResourcePtr theTREEResPtr) |
{ |
OSErr theErr = noErr; |
if (theTREEResPtr != nil) { |
*theType = theTREEResPtr->type; |
} |
else { |
theErr = kNilPtrErr; |
} |
return theErr; |
} |
OSErr GetIDFromTREE (long *theID, TREEResourcePtr theTREEResPtr) |
{ |
OSErr theErr = noErr; |
if (theTREEResPtr != nil) { |
*theID = theTREEResPtr->ID; |
} |
else { |
theErr = kNilPtrErr; |
} |
return theErr; |
} |
OSErr GetStringFromTREE (Str255 theString, TREEResourcePtr theTREEResPtr) |
{ |
OSErr theErr = noErr; |
short i; |
if (theTREEResPtr != nil) { |
for (i = 0; i < theTREEResPtr->name[0] + 1; i++) { |
theString[i] = theTREEResPtr->name[i]; |
} |
} |
else { |
theString[0] = 0; |
theErr = kNilPtrErr; |
} |
return theErr; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-14