Introduction and Installation
Rejecto is an out-of-vocabulary rejection plugin for the LanguageModelGenerator of OpenEars® for use with English and other compatible language models.
It is sometimes the case, especially with small vocabularies, that Pocketsphinx will report unrelated words as being matches for its vocabulary. Rejecto adds an out-of-vocabulary rejection model that increases the probability that words which are not in your vocabulary will not be recognized as words which are in your vocabulary. It does this by listening for isolated speech sounds (phonemes, like "AH" and "K") which do not map to the words you are actively listening for, and then rejecting recognitions in which they occur.
Rejecto is compatible with the English acoustic model AcousticModelEnglish.bundle and the other compatible acoustic models found at the <a/ href="https://www.politepix.com/openears/languagedownloads">acoustic model download page.
Rejecto can be purchased at the Politepix shop here and we recommend thoroughly evaluating the demo version before purchasing, which can be downloaded from this shop page. The installation and usage process is the same for both the demo and licensed version, but the demo times out after 3 minutes of use and can't be submitted to the App Store. The best way to get started using Rejecto is to get a tutorial from the Politepix interactive tutorial tool. Steps for getting started and more in-depth documentation are also provided on this page.
How to install and use Rejecto:
Rejecto is a plugin for OpenEars, so it is added to an already-working OpenEars project in order to enable new OpenEars features. In these instructions we are using the OpenEars sample app as an example for adding the plugin and new features, but the steps are basically the same for any app that already has a working OpenEars installation. Please note that Rejecto requires OpenEars 2.5 or greater. Rejecto also works with RapidEars versions 2.5 or greater.
Download and try out the OpenEars distribution and try the OpenEars sample app out. Rejecto is a plug-in for OpenEars that is added to an OpenEars project so you first need a known-working OpenEars app to work with. The OpenEars sample app is fine for this to get started. You can also get a complete tutorial on both creating an OpenEars app and adding Rejecto to it using the automatic customized tutorial.
Open up the OpenEars Sample App in Xcode. Drag your downloaded RejectoDemo.framework into the OpenEars sample app project file navigator.
Open up the Build Settings tab of your app or OpenEarsSampleApp and find the entry "Other Linker Flags" and add the linker flag "-ObjC". Do this for debug and release builds. More explanation of this step can be seen in the tutorial by selecting the "speech recognition which ignores spoken words which aren't in the vocabulary" tutorial, which will also show exactly how to use the new methods added by Rejecto.
Next, navigate to Xcode's Build Settings for your target and find the setting "Framework Search Paths".
If adding the framework in previous step did not automatically add it to "Framework Search Paths", add it manually. You can find the path by going into the Project Navigator (the main Xcode project file view), finding and then selecting your just-added RejectoDemo.framework, and typing ⌘⌥-1 to open the File Inspector for it (it may already be open – it is the narrow window pane on the far right of the main Xcode interface). The full path to your added framework is shown under "Identity and Type"->"Full Path". The "Framework Search Path" is this path minus the last path element, so if it says /Users/you/Documents/YourApp/Resources/Framework/RejectoDemo.framework, the path to add to "Framework Search Paths" is /Users/yourname/Documents/YourApp/Resources/Framework/ and you should keep the "Recursive" checkbox unchecked.
While we're here, take a moment to look at your Framework Search Paths build setting and verify that it doesn't contain any peculiar entries (for instance, entries with many extra quotes and/or backslashed quote marks) and that each search path is on its own line and hasn't been concatenated to another entry, and that the setting isn't pointing to old versions of the frameworks you're installing that are in other locations.
With your demo download you can receive support via the forums, according to its rules of conduct. In order to receive forum support, it is necessary to have used accurate information with your initial demo download such as a valid email address and your name.
Once you have completed licensing of the framework for your app, forum support will continue to be available to you, and if you need private support via email it is possible to purchase a support contract or individual support incidents at the shop.
Licensing the framework requires giving the exact application name that the framework will be linked to, so don't purchase the license until you know the app name, and again, please try the demo first. It is not possible to change bundle IDs after a purchase, and there are no refunds post-purchase, due to the ability to completely test the comprehensive demo over a full development period.
Please read on for the Rejecto documentation.
OELanguageModelGenerator+Rejecto Category Reference
A plugin which adds the ability to reject out-of-vocabulary words and statements when using OpenEars or RapidEars speech recognition. It is always necessary to run Rejecto while using a Rejecto model. There is no support for use of the output Rejecto model without running the plugin, since features of the plugin are developed on the assumption that it will be in use when its features are needed.
First, find the line
What to add to your OpenEars implementation:
#import <OpenEars/OELanguageModelGenerator.h>in your app and add the following line right underneath it:
#import <RejectoDemo/OELanguageModelGenerator+Rejecto.h>Next, change this line where you create a language model:
NSError *err = [lmGenerator generateLanguageModelFromArray:words withFilesNamed:name forAcousticModelAtPath:[OEAcousticModel pathToModel:@"AcousticModelEnglish"]];to use this method instead:
NSError *err = [lmGenerator generateRejectingLanguageModelFromArray:words withFilesNamed:name withOptionalExclusions:nil usingVowelsOnly:FALSE withWeight:nil forAcousticModelAtPath:[OEAcousticModel pathToModel:@"AcousticModelEnglish"]]; // Change "AcousticModelEnglish" to "AcousticModelSpanish" to create a Spanish Rejecto model.You will use the same array for languageModelArray and the same files name for fileName as you did with the old generateLanguageModelFromArray method, and to get started you can use the value "nil" for optionalExclusions, vowelsOnly, and weight, since they are there to help you refine your results and might not be needed. You can learn more about fine-tuning your results with those optional parameters in the Rejecto documentation.
- It isn't necessary to use optionalExclusions in order to try to tell Rejecto not to add a phoneme that is equivalent to a word in your vocabulary (for instance, Rejecto will add a phoneme by default that represents the "I" sound in the word "I" and the word "EYE", but if those words (or another word using the "I" sound by itself) are in your vocabulary, it will automatically not add the rejection phoneme that has the "I" sound.
It is only necessary to use optionalExclusions in the uncommon event that there is a phoneme that is being perceived more frequently than it is spoken, to the detriment of your speech detection of words that are really in your vocabulary.
|- (NSError *) generateRejectingLanguageModelFromArray:||(NSArray *)||languageModelArray|
lmGenerator.generateRejectingLanguageModel(from: [Any]!, withFilesNamed: String!, withOptionalExclusions: [Any]!, usingVowelsOnly: Bool, withWeight: NSNumber!, forAcousticModelAtPath: String!)
This is the method which replaces OpenEars' OELanguageModelGenerator's generateLanguageModelFromArray: method in a project which you have added this plugin to. It generates a language model from an array of NSStrings which are the words and phrases you want OEPocketsphinxController or OEPocketsphinxController+RapidEars to understand. Putting a phrase in as a string makes it somewhat more probable that the phrase will be recognized as a phrase when spoken.
fileName is the way you want the output files to be named. Please give your language models unique names within your session if you want to switch between them, so there is no danger of the engine getting confused between new and old models and dictionaries at the time of switching.
If this method is successful it will return nil. If it returns nil, you can use the methods pathToSuccessfullyGeneratedDictionaryWithRequestedName: and pathToSuccessfullyGeneratedLanguageModelWithRequestedName: or pathToSuccessfullyGeneratedGrammarWithRequestedName: to get your paths to your newly-generated language models and grammars and dictionaries for use with OEPocketsphinxController. If it doesn't return nil, it will return an error which you can check for debugging purposes.
Pass in the path to the acoustic model you want to use, e.g. [OEAcousticModel pathToModel:"AcousticModelEnglish"] or [OEAcousticModel pathToModel:@"AcousticModelSpanish"] or other Rejecto-compatible models you may be using (to be Rejecto-compatible a model needs to have a grapheme to phoneme model which has to be created by Politepix, so inquire about this at the forums if your model is missing this. Being Rejecto-compatible does not mean that results will be great or that Politepix will be able to give support for your results with models other than the default English model.
optionalExclusions can either be set to nil, or given an NSArray of NSStrings which contain phonemes which you do not want to have added to the rejection model. A case in which you might want to do this is when you have over-active rejection such that words that are really in the vocabulary are being rejected.
You can first turn on deliverRejectedSpeechInHypotheses: in order to see which phonemes are being detected overzealously and then you can add them to the exclusionArray. Set this parameter to nil if you aren't using it.
usingVowelsOnly allows you to limit the rejection model to only vowel phonemes, which should improve performance in cases where that is desired. Set this parameter to FALSE if you aren't using it.
The last optional parameter is weight, which should usually be set to nil, but can also be set to an NSNumber with a floatValue that is greater than zero and equal or less than 2.0. This will increase or decrease the weighting of the rejection model relative to the rest of the vocabulary.
If it is less than 1.0 it will reduce the probability that the rejection model is detected, and if it is more than 1.0 it will increase the probability that the rejection model is detected. Only use this if your testing reveals that the rejection model is either being detected too frequently, or not frequently enough.
It defaults to 1.0 and if you don't set it to anything (and you shouldn't, unless you have reason to believe that you should increase or decrease the probability of the rejection model being detected) it will automatically use the right setting. If you set it to a value that is equal to 1.0, or zero or less, or more than 2.0, the weight setting will be ignored and the default will be used. An NSNumber with a float looks like this: [NSNumber numberWithFloat:1.1]. The weight setting has no effect on the rest of your vocabulary, only the rejection model probabilities. Set this parameter to nil if you aren't using it.
|- (void) deliverRejectedSpeechInHypotheses:||(BOOL)||deliverRejectedSpeech|
Rejecto defaults to hiding recognized statements which are not words from your vocabulary (out of vocabulary recognitions), however if you want to see them for troubleshooting purposes you can set this method to TRUE.
If you do not need to see them, you don't have to run the method since the default is for hypotheses with Rejecto phonemes only to not be returned.