/// <summary> /// Returns the normalized words for the given recognizable /// </summary> /// <param name="recognizable"></param> /// <param name="language"></param> /// <returns></returns> public static IEnumerable <IList <string> > GetWordsNormalized(ISpeechRecognizable recognizable, string language) { //TODO speech: cache this in the recognizable var triggers = recognizable.SpeechTriggers; if (triggers?.Count > 0) { return(triggers.Select(sentence => GetWordsNormalized(ToWords(sentence, language), language))); } return(new IList <string> [0]); }
/// <summary> /// Matches the transcribed <see cref="Text"/> against the given recognizable's <see cref="ISpeechRecognizable.SpeechTriggers"/>. /// </summary> /// <param name="recognizable"></param> /// <param name="state"> /// The <see cref="SpeechRecognitionMatchResult.State"/> from the previous matching operation. /// This is used to avoid detecting the same trigger multiple times while the recognizer is still transcribing the full sentence (in not <see cref="WordResult"/> mode), /// but also used to to puzzle single words together in <see cref="WordResult"/> mode. /// </param> /// <returns></returns> public SpeechRecognitionMatchResult Match(ISpeechRecognizable recognizable, SpeechRecognitionMatchState state = null) { //TODO speech: when the recognizer switches the detected language, we might get the exact same text twice with different resultIDs. e.g. //(349200000|de-DE) hello there //(352100000|en-US) hello there //=> probably check on a change in language and remove words that were already included in the previous state var newState = GetMatchState(state); var result = new SpeechRecognitionMatchResult() { State = newState, Recognizable = recognizable }; var words = GetWordsNormalized(newState.WordsRemaining, Language); if (words.Count == 0) { //nothing to match return(result); } int iCandidate = -1; foreach (var triggerWords in GetWordsNormalized(recognizable, Language)) { ++iCandidate; if (triggerWords.Count == 0) { continue; } //check if triggerWords are included in words for (int iWords = 0; iWords < words.Count; ++iWords) { if (iWords + triggerWords.Count > words.Count) { break; } bool equals = true; for (int iTrigger = 0; iTrigger < triggerWords.Count; ++iTrigger) { if (words[iWords + iTrigger] != triggerWords[iTrigger]) { equals = false; break; } } if (equals) { //matched Logger.LogTrace($"Result {ResultID}: Matched words '{recognizable.SpeechTriggers.ElementAt(iCandidate)}' in spoken '{Text}'[{newState.WordsUsedIndex}] ({Language})"); result.Success = true; newState.AddWordsUsed(iWords + triggerWords.Count); return(result); } } } return(result); }