/// <summary> /// There is some delay in SR processing. the method is to guesstimate how many word the reader /// had been reading ahead when the SR return the result. /// </summary> /// <param name="currentSpeedStartIndex"></param> /// <param name="textArray"></param> /// <returns></returns> private int getGuessAheadCount(int currentSpeedStartIndex, string[] textArray) { int increment = 0; if (guessAhead && EBookInteractiveSystem.lookAheadDivider > 0 && syllableArray.Length >= textArray.Length + currentSpeedStartIndex) { int syCount = 0; for (int i = currentSpeedStartIndex; i < textArray.Length + currentSpeedStartIndex; i++) { syCount += syllableArray[i]; } int syIn = syCount / EBookInteractiveSystem.lookAheadDivider; //one syllable forward for every lookAheadDivide if (syIn < INITIAL_LOOK_AHEAD) { //The highlighting seems slow in the first second of a speech, let's highlight 2 syllables //ahead in the beginning of a speech syIn = INITIAL_LOOK_AHEAD; } int enInc = currentSpeedStartIndex + textArray.Length; if (maxSyllableAhead > 0) { //Debug.WriteLine("Time pier syllable=" + timePerSyllable); if (syIn > maxSyllableAhead) { syIn = (int)maxSyllableAhead; } } string currentEndWord = ""; if (enInc > 0 && enInc <= allSpeechText.Length) { currentEndWord = allSpeechText[enInc - 1]; } Boolean cont = true; while (syIn > 0 && cont) { if (enInc < syllableArray.Length) { string guessWord = allSpeechText[enInc]; //if the current end word has pause punctuation, stop look ahead if (EBookUtil.containPausePunctuation(currentEndWord)) { Debug.WriteLine("currentEndWord \"" + currentEndWord + "\" contains pause, stop look ahead"); break; } else if (EBookUtil.containPausePunctuation(guessWord)) { //reduce 4 syllables from enInc syIn -= 3; //no guess ahead if there is any possible pause in guess ahead word. //Debug.WriteLine("guessWord \"" + guessWord + "\" contains pause, stop look ahead"); //cont = false; } if (syIn >= syllableArray[enInc]) { increment++; } syIn -= syllableArray[enInc]; enInc++; } else { break; } } Debug.WriteLine("guess " + increment + " word(s) ahead"); } return(increment); }
/* * return 1 if the result is a complete speech and it is the end of the page. */ private int processSpeechResult(string result, int startInd, bool isH, float confidence, double duration) { //lock this method, in case the this method will take more time than the SR lock (lockThis) { int ret = 0; string[] arr = result.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries); if (isH) { int increment = 0; if (guessAhead && EBookInteractiveSystem.lookAheadDivider > 0 && syllableArray.Length >= arr.Length + startInd) { //numOfHypothsis++; int syCount = 0; for (int i = startInd; i < arr.Length + startInd; i++) { syCount += syllableArray[i]; } int syIn = syCount / EBookInteractiveSystem.lookAheadDivider; //one syllable forward for every lookAheadDivide if (syIn < INITIAL_LOOK_AHEAD) { //The highlighting seems slow in the first second of a speech, let's highlight 2 syllables //ahead in the beginning of a speech syIn = INITIAL_LOOK_AHEAD; } int enInc = startInd + arr.Length; if (maxSyllableAhead > 0) { //Debug.WriteLine("Time pier syllable=" + timePerSyllable); if (syIn > maxSyllableAhead) { syIn = (int)maxSyllableAhead; } } string currentEndWord = ""; if (enInc > 0 && enInc <= allSpeechText.Length) { currentEndWord = allSpeechText[enInc - 1]; } Boolean cont = true; while (syIn > 0 && cont) { if (enInc < syllableArray.Length) { string guessWord = allSpeechText[enInc]; //if the current end word has pause punctuation, stop look ahead if (EBookUtil.containPausePunctuation(currentEndWord)) { Debug.WriteLine("currentEndWord \"" + currentEndWord + "\" contains pause, stop look ahead"); break; } else if (EBookUtil.containPausePunctuation(guessWord)) { //reduce 4 syllables from enInc syIn -= 3; //no guess ahead if there is any possible pause in guess ahead word. //Debug.WriteLine("guessWord \"" + guessWord + "\" contains pause, stop look ahead"); //cont = false; } if (syIn >= syllableArray[enInc]) { increment++; } syIn -= syllableArray[enInc]; enInc++; } else { break; } } Debug.WriteLine("guess " + increment + " word(s) ahead"); } //ONLY DISPLAY INTERMIDIATE RESULT WITH CONFIDENCE SCORE GREATER THAN HYP_THRESHOLD if (confidence > HYP_THRESHOLD) { if (startInd == lastSegPosition) //continue with last segment { startIndex = confirmedStartIndex; hypothesisEndIndex = arr.Length + lastSegPosition - 1; endIndex = hypothesisEndIndex + increment; } else if (arr.Length > 1) //jumping to onther sentence when at least two word in the speech { int gap = startInd - confirmedEndIndex; if (gap > 0 && gap <= SPEECH_JUMP_GAP_THRESHOLD) { //if reader skip maximum of SPEECH_JUMP_GAP_THRESHOLD, consider //the continue highlight the sentence } else { startIndex = startInd; } hypothesisEndIndex = arr.Length + startInd - 1; endIndex = hypothesisEndIndex + increment; } } } else { //duration != -1 only when !isH, so we need to estimate the time //per syllable for the next scentence using the previous speech int syCount = 0; for (int i = startInd; i < arr.Length + startInd; i++) { syCount += syllableArray[i]; } timePerSyllable = duration / syCount; Trace.WriteLine("timePerSyllable: " + timePerSyllable); maxSyllableAhead = (int)(maxLag / timePerSyllable); // numOfHypothsis = 0; if (startInd == lastSegPosition) { //if number of confirmed word in the complete speech is one word less than imcomplete speech, //we can treat the last imcomplete speech as complete int completeEndIndex = arr.Length + lastSegPosition - 1; if (endIndex - completeEndIndex != 1) { endIndex = completeEndIndex; } lastSegPosition = endIndex + 1; } else { int gap = startInd - lastSegPosition; if (gap > 0 && gap <= SPEECH_JUMP_GAP_THRESHOLD) { //if reader skip maximum of SPEECH_JUMP_GAP_THRESHOLD, consider //the continue highlight the sentence } else { startIndex = startInd; } endIndex = arr.Length + startInd - 1; lastSegPosition = endIndex + 1; } confirmedStartIndex = startIndex; confirmedEndIndex = endIndex; confirmedLastSegPosition = lastSegPosition; if (mode != Mode.REPLAY) { //EBookSRDevice rec = EBookSRDevice.GetInstance(); //reach the end of the page if (confirmedEndIndex == allSpeechText.Length - 1) { //stop SR when transitioning to the next page //rec.enableSR(false); //ret = 1; //AbstractEBookEvent.raise(new FinishPageEvent()); } else { string cfgPath = storyDirectory + "\\" + GRAMMAR_TMP_DIR + "\\" + currentPage.GetPageNumber() + "_" + (endIndex + 1) + ".cfg"; if (!defaultStartIndexes.Contains(endIndex + 1)) { //rec.enableSR(false); //rec.UnloadOnGoingGrammar(); Grammar g = new Grammar(cfgPath); g.Weight = EBookConstant.NEXT_WORD_WEIGHT; g.Priority = EBookConstant.NEXT_WORD_PRIORITY; //rec.LoadOnGoingGrammar(g); ActivityExecutor.add(new InternalReloadOnGoingGrammarActivity(g)); Debug.WriteLine("Load onGoing grammar " + cfgPath); //rec.GenerateAndLoadOnGoingGrammars(allSpeechText,endIndex+1); //rec.enableSR(true); } else { //the next sentence has higher priority //rec.ReloadAndChangeGrammarPriority(endIndex + 1); ActivityExecutor.add(new InternalChangeGrammarPriorityActivity(endIndex + 1)); } } } if (mode != Mode.RECORD && confirmedEndIndex == allSpeechText.Length - 1) { //the complete recognized result reaches the end of the page ret = 1; } //Detect speech and complete //AbstractEBookEvent.raise(new CompleteSpeechEvent()); } Debug.WriteLine("startIndex=" + startIndex); Debug.WriteLine("endIndex=" + endIndex); Debug.WriteLine("lastSegPosition=" + lastSegPosition); Debug.WriteLine("confirmedStartIndex=" + confirmedStartIndex); Debug.WriteLine("confirmedEndIndex=" + confirmedEndIndex); Debug.WriteLine("confirmedLastSegPosition=" + confirmedLastSegPosition); return(ret); } }