I'd like to use the ios SFSpeechRecognizer
to recognize a closed set of words and phrases. Is there a way to specify these and remove all other possibilities? I cannot seem to find a way to do this.

- 1,955
- 1
- 14
- 37
3 Answers
You can try to use contextualStrings property of SFSpeechAudioBufferRecognitionRequest to set high priority or to set some words that are not in vocabulary. For more info look here: https://developer.apple.com/documentation/speech/sfspeechrecognitionrequest/1649391-contextualstrings?language=objc
SFSpeechAudioBufferRecognitionRequest *recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
recognitionRequest.contextualStrings = @[@"Your specific word", @"short custom phrases that are unique to your app"];

- 161
- 1
- 10
I think you cannot limit SFSpeechRecognizer
's vocabulary, but you can fire action only if the words you want are recognized.
When you get your output, you can try something like this:
self.recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
if result == "Desired word one" {
// Do something
} else if result == "Desired word two" {
// Do something else
} else {
// Don't do anything
}
})

- 2,272
- 1
- 27
- 47
-
That’s too bad. My intention was to make certain words likelier to be candidates, not to ignore transcriptions containing out-of-vocabulary words. – synchronizer Oct 08 '20 at 23:21
-
Do you mean you want a personal vocabulary that contains "special" words like "expecto patronum"? – Giuseppe Garassino Oct 09 '20 at 07:07
-
No, and SFSpeechRecognizer is terrible at doing that even if it has that feature supposedly. I mean that if I had control over what algorithm they used to recognize words, supposing they had several candidates for a result, I’d want to make some of the candidates non-existent. For example, the recognizer is bad at math terms. “N numbers” yet erroneously recognizes words as company names I don’t care about without any way of knowing what other choices there were. I think there’s no way to guide the algorithm internally though. It is what it is. – synchronizer Oct 10 '20 at 15:42
-
I see... it would be very useful, but I don't think it is possible. Anyway, have you tried SiriKit? https://developer.apple.com/documentation/sirikit I never used it, but I remember I read somewhere you could have personal vocabulary. – Giuseppe Garassino Oct 11 '20 at 03:56
-
It won’t work for my purposes unfortunately. Thanks anyway. – synchronizer Oct 11 '20 at 15:23
After some trials and error, the best solution is a mix between Mrsantateam and Giuseppe Garassino's answers.
you can first specify all commands that should be "prioritized" by setting contextualStrings
...
var contextualString = ["hello world", "goodbye world"]
recognitionRequest.contextualStrings = contextualString
... And later filter those results in recognitionTask
:
recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
var isFinal = false
if let result = result {
for transcription in result.transcriptions {
print("Pondering \(result.bestTranscription.formattedString)")
if contextualString.contains(transcription.formattedString.lowercased()) {
print("Found \(transcription.formattedString)")
}
}
}
//...
}
Sample code can be found at https://developer.apple.com/documentation/speech/recognizing_speech_in_live_audio if you want to play with it and test its limits

- 2,268
- 3
- 28
- 38