Beispiel #1
0
        /// <summary>
        /// SR rejects the recent hypothesis result, roll the highlighting back to previous
        /// comfirmed text
        /// </summary>
        public void rollBackText()
        {
            numOfHypothsis = 0;

            lastSegPosition = confirmedLastSegPosition;
            startIndex      = confirmedStartIndex;
            endIndex        = confirmedEndIndex;
            processAnimation(endIndex);

            //construct the text without highlight if the rejected recognition is the first sentence/word of the page
            if (confirmedLastSegPosition == confirmedStartIndex && confirmedStartIndex == confirmedEndIndex &&
                confirmedEndIndex == 0)
            {
                string pageTextStr = constructPageText();
                ActivityExecutor.add(new InternalUpdatePageTextActivity(pageTextStr, currentPage.GetPageNumber()));
            }
            else
            {
                //construct html text with highlight
                constructTextAndDisplay();
            }
        }
Beispiel #2
0
 /// <summary>
 /// Interpret the meaning for a command speech.
 /// Caution: the string comparison in this function for the commands are
 /// rely on the script in command.grxml. If you can something in the command.grxml file
 /// you may need to edit command string in this function, vice versa.
 /// </summary>
 /// <param name="semantics"></param>
 private void processCommandSemantics(KeyValuePair <string, SemanticValue>[] semantics)
 {
     foreach (KeyValuePair <string, SemanticValue> each in semantics)
     {
         if (each.Key.CompareTo("NavigatePage") == 0)
         {
             if (each.Value.Value.ToString().CompareTo("[next]") == 0)
             {
                 ActivityExecutor.add(new InternalSpeechNavigatePageActivity(PageAction.NEXT));
             }
             else if (each.Value.Value.ToString().CompareTo("[previous]") == 0)
             {
                 ActivityExecutor.add(new InternalSpeechNavigatePageActivity(PageAction.PREVIOUS));
             }
             else
             {
                 int pageN = Convert.ToInt32(each.Value.Value);
                 ActivityExecutor.add(new InternalSpeechNavigatePageActivity(PageAction.GO_PAGE_X, pageN));
             }
         }
     }
 }
Beispiel #3
0
        public void playSyncAudio()
        {
            if (run)
            {
                Thread.Sleep(500);
                if (threax != null && threax.IsAlive)
                {
                    threax.Join();
                }
                Debug.WriteLine("##start replay audio [" + currentAudioIndex + "]");
                if (currentAudioIndex < audioPlayList.Count && run)
                {
                    string audioPath = audioPlayList.ElementAt(currentAudioIndex);
                    int    pas       = currentAudioIndex;
                    threax = new Thread(() => regenerateSREvent(pas));
                    threax.Start();

                    ActivityExecutor.add(new InternalReplayAudioActivity(audioPath, currentAudioIndex));

                    currentAudioIndex++;
                }
            }
        }
        void recEngine_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            float  confidence = e.Result.Confidence;
            string textResult = e.Result.Text;

            string grammarName = e.Result.Grammar.Name;
            string ruleName    = e.Result.Grammar.RuleName;

            double audioDuration = -1;

            if (e.Result.Audio != null)
            {
                //Looks like we can't get the audio duration for hypothesis result, BUG in Microsoft?
                audioDuration = e.Result.Audio.Duration.TotalMilliseconds;
            }


            KeyValuePair <string, SemanticValue>[] kvp = e.Result.Semantics.ToArray();

            //AbstractEBookEvent.raise(new RecognitionResultEvent(confidence,textResult,true,
            //    kvp,grammarName,ruleName, audioDuration,null));
            ActivityExecutor.add(new InternalSpeechRecognitionResultActivity(confidence, textResult, true,
                                                                             kvp, grammarName, ruleName, audioDuration, null));
            String timeStamp = GetTimestamp(DateTime.Now);

            string text = "\n" + e.Result.Confidence + "\t" + e.Result.Text + "(Hypothesis)\t" +
                          e.Result.Semantics.Value + "\tgrammarName=" + e.Result.Grammar.Name + "\truleName=" +
                          e.Result.Grammar.RuleName + "\t" + timeStamp;

            Trace.WriteLine(text);


            //double timeNow = EBookUtil.GetUnixTimeMillis();
            //double mun = timeNow - speechTurnAroundTime;
            //speechTurnAroundTime = timeNow;
            //eachSpeechTimes.Add(mun);
        }
        //String lastCompleteResult = "";
        void recEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            float  confidence = e.Result.Confidence;
            string textResult = e.Result.Text;
            //string semantics = e.Result.Semantics.Value + "";
            string grammarName   = e.Result.Grammar.Name;
            string ruleName      = e.Result.Grammar.RuleName;
            double audioDuration = -1;

            if (e.Result.Audio != null)
            {
                audioDuration = e.Result.Audio.Duration.TotalMilliseconds;
            }
            //string phonetic = "";
            //foreach (RecognizedWordUnit unit in e.Result.Words)
            //{
            //    phonetic += unit.Pronunciation + " ";
            //}
            //Debug.WriteLine(textResult + "[" + phonetic.TrimEnd() + "]");

            Debug.WriteLine("audio duration=" + audioDuration);
            KeyValuePair <string, SemanticValue>[] kvp = e.Result.Semantics.ToArray();


            string fileP   = null;
            string relPath = null;

            //only write audio file when given path is not null
            if (saveAudioPath != null)
            {
                string indexerStr = waveFileNameIndexer + "";
                while (indexerStr.Length < 4)
                {
                    indexerStr = "0" + indexerStr;
                }

                fileP = saveAudioPath + "\\" + indexerStr + ".wav";

                relPath = EBookUtil.convertAudioToRelativePath(@fileP);
            }



            //AbstractEBookEvent.raise(new RecognitionResultEvent(confidence, textResult, false,
            //    kvp,grammarName,ruleName,audioDuration,@fileP));
            ActivityExecutor.add(new InternalSpeechRecognitionResultActivity(confidence, textResult, false,
                                                                             kvp, grammarName, ruleName, audioDuration, relPath));

            //only write audio file when given path is not null
            if (fileP != null)
            {
                //write audio to file
                FileStream stream = new FileStream(fileP, FileMode.Create);

                e.Result.Audio.WriteToWaveStream(stream);
                stream.Flush();
                stream.Close();
                unconfirmSaveAudioList.Add(fileP);
                Trace.WriteLine("write to file " + fileP);
                waveFileNameIndexer++;
            }
            String timeStamp = GetTimestamp(DateTime.Now);

            string text = "\n" + e.Result.Confidence + "\t" + e.Result.Text + "(complete)\t\t" +
                          e.Result.Semantics.Value + "\t" + e.Result.Grammar.Name + "\t" + timeStamp;

            Trace.WriteLine(text);
        }
Beispiel #6
0
 /// <summary>
 /// Restart the system
 /// </summary>
 public void restart()
 {
     ActivityExecutor.add(new UserRestartSystemActivity());
 }
Beispiel #7
0
        /// <summary>
        /// process the recognition result, the recognition result can be the
        /// hypothesis result or the complete result.
        /// </summary>
        /// <param name="confidence"></param>
        /// <param name="textResult"></param>
        /// <param name="isHypothesis"></param>
        /// <param name="semantics"></param>
        /// <param name="grammarName"></param>
        /// <param name="ruleName"></param>
        /// <param name="audioDuration"></param>
        /// <param name="wavPath"></param>
        public void processRecognitionResult(float confidence, string textResult,
                                             bool isHypothesis, KeyValuePair <string, SemanticValue>[] semantics, string grammarName,
                                             string ruleName, double audioDuration, string wavPath)
        {
            //handle result if the recognized speech is a command
            if (grammarName.CompareTo("command") == 0)
            {
                if (!isHypothesis && confidence * 100 > EBookInteractiveSystem.commandConfidenceThreshold)
                {
                    processCommandSemantics(semantics);
                }
            }
            //handle result if this is story text
            else
            {
                int start = -1; //the index of the first word of the recognized text in the current page
                //process the story annotations
                if (semantics != null && semantics.Length > 0)
                {
                    foreach (KeyValuePair <string, SemanticValue> each in semantics)
                    {
                        if (each.Key.CompareTo("startIndex") == 0)
                        {
                            start = Convert.ToInt32(each.Value.Value);
                        }
                    }
                }

                if (start == -1)
                {
                    string rule = ruleName;
                    if (rule.StartsWith("index_"))
                    {
                        string startIndex = rule.Substring(6);
                        if (startIndex.Length > 0)
                        {
                            start = Convert.ToInt32(startIndex);
                        }
                    }
                }

                //process the highlighting before animation (try to underline the text as fast as possible)
                Debug.WriteLine(textResult);
                Trace.WriteLine("start process Text time: " + DateTime.Now.ToString("yyyyMMddHHmmssfff"));
                int isEndOfPage = processSpeechResult(textResult, start, isHypothesis,
                                                      confidence, audioDuration);
                constructTextAndDisplay();
                Trace.WriteLine("end process Text time: " + DateTime.Now.ToString("yyyyMMddHHmmssfff"));


                //for some reasons, the hypothesis results do not contain any semantic results, so
                //we have to find it manually
                if (isHypothesis)
                {
                    string[] tmp = textResult.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);
                    //it is offen misrecognize the first word in a speech.
                    //generate animation when hypothsis text is greater than 1
                    if (tmp.Length > 1)
                    {
                        processHypothesisAnimation(tmp.Length, start);
                    }
                }
                else
                {
                    string[] tmp = textResult.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);
                    processAnimation(tmp.Length + start);

                    //keep the last action in the list, remove rest of the them
                    if (isEndOfPage == 1)
                    {
                        //Debug.WriteLine("generating a finishpageactivity "+isHypothesis);
                        ActivityExecutor.add(new InternalFinishPageActivity());
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// construct the highlight text and fire up a internal activity
        /// </summary>
        private void constructTextAndDisplay()
        {
            //if startIndex not equals to confirmedStartIndex, the hypothesis result
            //starts from different position.


            string displayText = "<span class='storytext'>";

            for (int i = 0; i < allSpeechTextHTML.Length; i++)
            {
                //the on going speech is not yet confirmed
                if (startIndex == confirmedStartIndex && endIndex > confirmedEndIndex && startIndex != -1)
                {
                    //if it is the beginning (no confirmed speech)
                    if (confirmedEndIndex == 0)
                    {
                        if (startIndex == i && endIndex == i)
                        {
                            if (endIndex > hypothesisEndIndex)
                            {
                                displayText += "<span class='hypothesis'>" + allSpeechTextHTML[i] + " </span> <span class='lookAhead'>";
                            }
                            else
                            {
                                displayText += "<span class='hypothesis'>" + allSpeechTextHTML[i] + " </span> ";
                            }
                        }
                        else if (startIndex == i)
                        {
                            displayText += " <span class='hypothesis'>" + allSpeechTextHTML[i] + " ";
                        }
                        else if (hypothesisEndIndex == i && hypothesisEndIndex < endIndex)
                        {
                            displayText += allSpeechTextHTML[i] + " </span> <span class='lookAhead'>";
                        }
                        else if (endIndex == i)
                        {
                            displayText += allSpeechTextHTML[i] + " </span> ";
                        }
                        else
                        {
                            displayText += allSpeechTextHTML[i] + " ";
                        }
                    }
                    else
                    {
                        if (startIndex == i && endIndex == i)
                        {
                            if (endIndex > hypothesisEndIndex)
                            {
                                displayText += "<span class='hypothesis'>" + allSpeechTextHTML[i] + " </span> <span class='lookAhead'>";
                            }
                            else
                            {
                                displayText += "<span class='hypothesis'>" + allSpeechTextHTML[i] + " </span> ";
                            }
                        }
                        else if (startIndex == i)
                        {
                            displayText += "<span class='highlight'>" + allSpeechTextHTML[i] + " ";
                        }
                        else if (confirmedEndIndex == i)
                        {
                            displayText += allSpeechTextHTML[i] + " </span> <span class='hypothesis'>";
                        }
                        else if (hypothesisEndIndex == i && hypothesisEndIndex < endIndex)
                        {
                            displayText += allSpeechTextHTML[i] + " </span> <span class='lookAhead'>";
                        }
                        else if (endIndex == i)
                        {
                            displayText += allSpeechTextHTML[i] + " </span> ";
                        }
                        else
                        {
                            displayText += allSpeechTextHTML[i] + " ";
                        }
                    }
                }
                //the on going speech is not yet confirmed and the hypothesis result starts from different position
                else if (startIndex != confirmedStartIndex && startIndex != -1)
                {
                    //display the confimred words
                    if (confirmedStartIndex == i && confirmedEndIndex == i)
                    {
                        displayText += "<span class='highlight'>" + allSpeechTextHTML[i] + " </span> ";
                    }
                    else if (confirmedStartIndex == i)
                    {
                        displayText += "<span class='highlight'>" + allSpeechTextHTML[i] + " ";
                    }
                    else if (confirmedEndIndex == i)
                    {
                        displayText += allSpeechTextHTML[i] + " </span> ";
                    }
                    else if (startIndex == i)
                    {
                        displayText += "<span class='hypothesis'>" + allSpeechTextHTML[i] + " ";
                    }
                    else if (endIndex == i)
                    {
                        displayText += allSpeechTextHTML[i] + " </span> ";
                    }
                    else
                    {
                        displayText += allSpeechTextHTML[i] + " ";
                    }
                }
                //all spoken speech are confirmed
                else
                {
                    if (startIndex == i && endIndex == i)
                    {
                        displayText += "<span class='highlight'>" + allSpeechTextHTML[i] + "</span> ";
                    }
                    else if (startIndex == i)
                    {
                        displayText += "<span class='highlight'>" + allSpeechTextHTML[i] + " ";
                    }
                    else if (endIndex == i)
                    {
                        displayText += allSpeechTextHTML[i] + "</span> ";
                    }
                    else
                    {
                        displayText += allSpeechTextHTML[i] + " ";
                    }
                }
            }
            displayText += "</span>";
            Debug.WriteLine(displayText);
            ActivityExecutor.add(new InternalUpdateTextHighLightActivity(displayText));
        }
Beispiel #9
0
        /// <summary>
        /// Process the result from speech recognizer. This method will figure out the
        /// highlighting, and generate the grammar that start from the last word it left off.
        /// </summary>
        /// <param name="result">The recognized text</param>
        /// <param name="currentSpeedStartIndex"></param>
        /// <param name="isH">indicate whether the result is a hypothesis</param>
        /// <param name="confidence">The confidence score between [0,1]</param>
        /// <param name="duration">the duration of the detected speech in millisecond</param>
        /// <returns>return 1 if the result is a complete speech and it is in the end of the page.</returns>
        private int processSpeechResult(string result, int currentSpeedStartIndex, bool isH, float confidence, double duration)
        {
            //lock this method, in case the this method will take more time than the next result from SR
            lock (lockThis)
            {
                int      ret = 0;
                string[] arr = result.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);

                if (isH)
                {
                    int increment = getGuessAheadCount(currentSpeedStartIndex, arr);

                    //ONLY DISPLAY INTERMIDIATE RESULT WITH CONFIDENCE SCORE GREATER THAN HYP_THRESHOLD
                    if (confidence > HYP_THRESHOLD)
                    {
                        if (currentSpeedStartIndex == lastSegPosition + 1) //continue with last segment
                        {
                            if (confirmedStartIndex != -1)
                            {
                                startIndex = confirmedStartIndex;
                            }
                            else
                            {
                                startIndex = currentSpeedStartIndex;
                            }
                            hypothesisEndIndex = arr.Length + lastSegPosition;
                            endIndex           = hypothesisEndIndex + increment;
                        }
                        else if (arr.Length > 1) //jumping to onther sentence when at least two word in the speech
                        {
                            int gap = 0;
                            if (confirmedEndIndex != -1)
                            {
                                if (currentSpeedStartIndex < confirmedEndIndex)
                                {
                                    //the reader jump to the text prior to the last confirmed text
                                    gap = SPEECH_JUMP_GAP_THRESHOLD + 1;
                                }
                                else
                                {
                                    gap = currentSpeedStartIndex - confirmedEndIndex;
                                }
                            }
                            else
                            {
                                gap = currentSpeedStartIndex;
                            }
                            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 = currentSpeedStartIndex;
                            }
                            hypothesisEndIndex = arr.Length + currentSpeedStartIndex - 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 = currentSpeedStartIndex; i < arr.Length + currentSpeedStartIndex; i++)
                    {
                        syCount += syllableArray[i];
                    }
                    timePerSyllable = duration / syCount;
                    Trace.WriteLine("timePerSyllable: " + timePerSyllable);
                    maxSyllableAhead = (int)(maxLag / timePerSyllable); //

                    numOfHypothsis = 0;
                    if (currentSpeedStartIndex == lastSegPosition + 1)
                    {
                        //if number of confirmed word in the complete speech is one word less than hypothesis speech,
                        //we can treat the last imcomplete speech as complete
                        int completeEndIndex = arr.Length + lastSegPosition;
                        if (endIndex - completeEndIndex == 1)
                        {
                            //the completed speed is one word less than the previous hypothesis speech
                        }
                        else
                        {
                            endIndex = completeEndIndex;
                        }
                        lastSegPosition = endIndex;
                    }
                    //the reader 'skip' the sentence
                    else
                    {
                        int gap = currentSpeedStartIndex - lastSegPosition + 1;
                        if (currentSpeedStartIndex < lastSegPosition)
                        {
                            gap = SPEECH_JUMP_GAP_THRESHOLD + 1;
                        }
                        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 = currentSpeedStartIndex;
                        }
                        endIndex        = arr.Length + currentSpeedStartIndex - 1;
                        lastSegPosition = endIndex;
                    }
                    confirmedStartIndex      = startIndex;
                    confirmedEndIndex        = endIndex;
                    confirmedLastSegPosition = lastSegPosition;
                    if (mode != Mode.REPLAY)
                    {
                        //reach the end of the page
                        if (confirmedEndIndex == allSpeechText.Length - 1)
                        {
                            //do nothing. We don't need to handle the end of the page for
                            //replay mode in this class
                        }
                        else
                        {
                            string cfgPath = storyDirectory + "\\" + GRAMMAR_TMP_DIR + "\\" +
                                             currentPage.GetPageNumber() + "_" + (endIndex + 1) + ".cfg";
                            if (!defaultStartIndexes.Contains(endIndex + 1))
                            {
                                Grammar g = new Grammar(cfgPath);
                                g.Weight   = EBookConstant.NEXT_WORD_WEIGHT;
                                g.Priority = EBookConstant.NEXT_WORD_PRIORITY;
                                ActivityExecutor.add(new InternalReloadOnGoingGrammarActivity(g));

                                Debug.WriteLine("Load onGoing grammar " + cfgPath);
                            }
                            else
                            {
                                //the next sentence has higher priority
                                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;
                    }
                }
                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);
            }
        }
Beispiel #10
0
        /// <summary>
        /// The method is to process a new page (or refresh a page).
        /// Generate necessary grammars for the current page.
        /// Generate text and display in browser.
        /// If Mode == REAL TIME, enable user to start from /jump to any sentence. otherwise,
        /// disable this feature.
        /// </summary>
        /// <param name="page">The page to be display in browser</param>
        /// <param name="mode">The story mode {read it now, record my voice}</param>
        public void process(Page page, Mode mode)
        {
            this.mode   = mode;
            currentPage = page;

            //reset parameters when process a new page
            resetParameters();
            retrivePageContent(page);

            if (mode != Mode.REPLAY)
            {
                List <SrgsDocument> srgsDocs = EBookUtil.GenerateGrammars(allSpeechText, annotationArray);
                Debug.WriteLine("generated " + srgsDocs.Count + " grammar files");

                //load grammars
                List <Grammar> gs = new List <Grammar>();
                //loop from srgsDocs.Count to 0 will give the earlier sentence the higher priority (if
                //two sentence contain the same word, Microsft choose the latest grammar that load into its engine).
                for (int i = srgsDocs.Count; --i >= 0;)
                {
                    string cfgPath = storyDirectory + "\\" + GRAMMAR_TMP_DIR + "\\" + page.GetPageNumber() + "_" + i + ".cfg";
                    Directory.CreateDirectory(storyDirectory + "\\" + GRAMMAR_TMP_DIR);

                    EBookUtil.CompileGrammarToFile(srgsDocs.ElementAt(i), cfgPath);

                    //allow user to start from new sentence in read time mode
                    if (mode == Mode.REALTIME)
                    {
                        if (i == 0 || (i > 0 && (EBookUtil.containEndOfSentencePunctuation(allSpeechText[i - 1]))))
                        {
                            defaultStartIndexes.Add(i);
                            Debug.WriteLine("loading grammar:" + cfgPath);
                            Grammar storyG = new Grammar(cfgPath);
                            storyG.Weight   = EBookConstant.DEFAULT_WEIGHT;
                            storyG.Priority = EBookConstant.DEFAULT_PRIORITY;

                            gs.Add(storyG);
                        }
                    }
                    else //in recording mode, only allow the reader to start from where she/he left off
                    {
                        if (i == 0)
                        {
                            defaultStartIndexes.Add(i);
                            Debug.WriteLine("loading grammar:" + cfgPath);
                            Grammar storyG = new Grammar(cfgPath);
                            storyG.Weight   = EBookConstant.DEFAULT_WEIGHT;
                            storyG.Priority = EBookConstant.DEFAULT_PRIORITY;

                            ActivityExecutor.add(new InternalReloadOnGoingGrammarActivity(storyG));
                        }
                    }
                }
                if (gs.Count > 0)
                {
                    ActivityExecutor.add(new InternalReloadStoryGrammarActivity(gs));
                }
            }
            string pageTextStr = constructPageText();

            ActivityExecutor.add(new InternalUpdatePageTextActivity(pageTextStr, page.pageNumber));
        }
Beispiel #11
0
        /*
         * 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);
            }
        }
Beispiel #12
0
        /*
         * If Mode == REAL TIME, enable jump to different sentence. otherwise, disable jump to different sentence
         */
        public void process(Page page, Mode mode)
        {
            this.mode   = mode;
            currentPage = page;

            //reset parameters when process a new page
            resetParameters();

            //retrieve data from cache
            if (enableCache && pageTextCached.ContainsKey(page.GetPageNumber()))
            {
                pageTextCached.TryGetValue(page.GetPageNumber(), out allSpeechText);
                pageTextHTMLCached.TryGetValue(page.GetPageNumber(), out allSpeechTextHTML);
                annotationArrayCached.TryGetValue(page.GetPageNumber(), out annotationArray);
                syllableArrayCached.TryGetValue(page.GetPageNumber(), out syllableArray);
            }
            else
            {
                List <string[]> pageText   = page.GetListOfTextArray();
                List <string>   annotation = page.GetListOfAnnotations();
                List <string>   annArray   = new List <string>();
                //cover list to array
                string whole     = "";
                string wholeHTML = "";
                //obtain the text and the text in HTML format for the current page
                for (int i = 0; i < pageText.Count; i++)
                {
                    if (pageText.ElementAt(i) == null)
                    {
                        wholeHTML = wholeHTML.TrimEnd() + "<br> ";
                    }
                    else
                    {
                        foreach (string str in pageText.ElementAt(i))
                        {
                            whole += str + " ";
                            if (str.Trim().Length == 0)
                            {
                                wholeHTML = wholeHTML.TrimEnd() + " ";
                            }
                            else
                            {
                                wholeHTML += str + " ";
                            }
                            annArray.Add(annotation.ElementAt(i));
                        }
                        //wholeHTML = wholeHTML.TrimEnd() + "<br> ";
                    }
                }
                whole             = whole.Replace("\"", "");
                allSpeechText     = whole.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);
                allSpeechTextHTML = wholeHTML.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries);
                annotationArray   = annArray.ToArray();
                syllableArray     = EBookUtil.CountSyllables(allSpeechText);


                //save the data to hash map, we can simply retrieve the page data when
                //the page get revisit again
                if (enableCache)
                {
                    pageTextCached.Add(page.GetPageNumber(), allSpeechText);
                    pageTextHTMLCached.Add(page.GetPageNumber(), allSpeechTextHTML);
                    annotationArrayCached.Add(page.GetPageNumber(), annotationArray);
                    syllableArrayCached.Add(page.GetPageNumber(), syllableArray);
                }
            }



            if (mode != Mode.REPLAY)
            {
                defaultStartIndexes.Clear();
                List <SrgsDocument> srgsDocs = EBookUtil.GenerateGrammars(allSpeechText, annotationArray);
                Debug.WriteLine("generated " + srgsDocs.Count + " grammar files");

                //load grammars
                List <Grammar> gs = new List <Grammar>();
                //loop from srgsDocs.Count to 0 will give the early sentence the priority.
                for (int i = srgsDocs.Count; --i >= 0;)
                {
                    string cfgPath = storyDirectory + "\\" + GRAMMAR_TMP_DIR + "\\" + page.GetPageNumber() + "_" + i + ".cfg";
                    Directory.CreateDirectory(storyDirectory + "\\" + GRAMMAR_TMP_DIR);
                    CompileGrammar(srgsDocs.ElementAt(i), cfgPath);
                    if (mode == Mode.REALTIME)
                    {
                        if (i == 0 || (i > 0 && (allSpeechText[i - 1].Contains("?") || allSpeechText[i - 1].Contains(".") ||
                                                 allSpeechText[i - 1].Contains("!"))))
                        {
                            defaultStartIndexes.Add(i);
                            Debug.WriteLine("loading grammar:" + cfgPath);
                            Grammar storyG = new Grammar(cfgPath);
                            storyG.Weight   = EBookConstant.DEFAULT_WEIGHT;
                            storyG.Priority = EBookConstant.DEFAULT_PRIORITY;

                            gs.Add(storyG);
                        }
                    }
                    else
                    {
                        if (i == 0)
                        {
                            defaultStartIndexes.Add(i);
                            Debug.WriteLine("loading grammar:" + cfgPath);
                            Grammar storyG = new Grammar(cfgPath);
                            storyG.Weight   = EBookConstant.DEFAULT_WEIGHT;
                            storyG.Priority = EBookConstant.DEFAULT_PRIORITY;

                            ActivityExecutor.add(new InternalReloadOnGoingGrammarActivity(storyG));
                        }
                    }
                }
                if (gs.Count > 0)
                {
                    ActivityExecutor.add(new InternalReloadStoryGrammarActivity(gs));
                }
            }
            string pageTextStr = constructPageText();

            ActivityExecutor.add(new InternalUpdatePageTextActivity(pageTextStr, page.pageNumber));
        }