/// <summary> /// Returns a new match state for this event and the given previous state (optional). /// </summary> /// <param name="recognizable"></param> /// <param name="state"></param> /// <returns></returns> protected SpeechRecognitionMatchState GetMatchState(SpeechRecognitionMatchState state) { SpeechRecognitionMatchState newState = new SpeechRecognitionMatchState() { Event = this }; if (state != null && ((!WordResult && state.ResultID == ResultID) || (WordResult && TimestampMillis - state.TimestampMillisEnd < 3000))) { //keep using the previous detection state newState.Previous.Add(state); } return(newState); }
/// <summary> /// Calls <see cref="Match(ISpeechRecognizable, SpeechRecognitionMatchState)"/> and returns the first result that matches well enough with the spoken words. /// </summary> /// <param name="recognizables"></param> /// <param name="state"></param> /// <returns></returns> public SpeechRecognitionMatchResult Match(IEnumerable <ISpeechRecognizable> recognizables, SpeechRecognitionMatchState state = null) { foreach (var recognizable in recognizables) { var result = Match(recognizable, state); if (result.Success) { return(result); } } return(new SpeechRecognitionMatchResult() { State = GetMatchState(state) }); }
/// <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); }