Synchronization Problem for SAPI or (text to speec

2019-03-03 16:43发布

问题:

I'm working on a project which will speak the content of browsed web page.Browser is made by me using WebControl. I'm using SAPI for speech engine. I wanted to highlight the line in web page while reading that trough SpVoice.speak. But the problem is that if I use this speak method in Asynchronous way,then only last line of the web page getting highlighted,because the loop doesn't wait for the voice to complete. Thus it happens so fast that only last line is shown as highlighted.Highlight method is using a reference Microsoft mshtml. CODE:

SpeechLib.SpVoice sound_object = new SpeechLib.SpVoice();
bool highlight(string senten)
    {
        if (senten != null)
        {
            IHTMLDocument2 doc = (IHTMLDocument2)GetCurrentBrowser().Document.DomDocument;
            IHTMLSelectionObject sel = (IHTMLSelectionObject)doc.selection;
            IHTMLTxtRange rng = (IHTMLTxtRange)sel.createRange();
            rng.collapse(false);
            if (rng.findText(senten, 1000000, 0))
            {
                rng.select();
                return true;
            }
            else
            {
                return false;
            }

        }
        else
        { return false; }

    }

private void Read_ButtonSpkBAR_Click(object sender, EventArgs e) { //call for getting sourceCode gettingSourceCode();

        if (highlightToolStripMenuItem.Checked == true)
        {

            if (PAUSE)
            {
                sound_object.Resume();
                PAUSE = false;
            }
            else
            {
                sound_object.Rate = tempoRate;
                sound_object.Volume = volume;


                string[] splitSentences = Regex.Split(SourceCode, @"(?<=['""A-Za-z0-9][\.\!\?\u2424])\s+(?=[A-Z])");



                for (int i = 0; i < splitSentences.Length; i++)
                {


                    highlight(splitSentences[i]);
                    //MessageBox.Show(splitSentences[i]);

                    sound_object.Speak(splitSentences[i],SpeechLib.SpeechVoiceSpeakFlags.SVSFlagsAsync);




                }
            }
        }

Now if I call the sound_object.speak() in a Synchronize way which is sound_object.Speak(splitSentences[i]); then the loop wait for the voice to complete,but I don't know why it didn't show highlighted line. The software get hanged while speaking.That means WebBrowser doesn't do anything while speaking,but the speaking procedure works fine at that time.

For checking the highlight I put a messagebox inside of loop and seen that the lines get highlighted if the loop wait for the "OK" button to be pushed of the messagebox.But this isn't a good idea at all to push "OK" button for each line. So can anyone please help me that what is the problem and how can I use the SAPI or any other speech engine in a efficient way, so that I can read and highlight altogether without getting the browser hanged........

回答1:

get all the sentences into one string, and call the speak just once. replace ur for loop with below:

string str1 = "";
for (int i = 0; i < splitSentences.Length; i++) 
{ 
     str1 += highlight(splitSentences[i]); 
}
sound_object.Speak(str1, SpeechLib.SpeechVoiceSpeakFlags.SVSFlagsAsync);

hope this helps!



回答2:

You need to do the next line after the previous line finishes, using the TTS's completion event.