0

这是一个微软语音 api 相关的问题:

这个想法是,当 SpeechSynthesizer 触发 SpeakStarted 事件时,我想知道 SpeechSynthesizer 在这个事件中会说什么。所以我可以同步语音和GUI显示。

代码:

SpeechSynthesizer _reader = new SpeechSynthesizer();


_reader.SpeakStarted += new EventHandler<SpeakStartedEventArgs>(_reader_SpeakStarted);


  void _reader_SpeakStarted(object sender, SpeakStartedEventArgs e)
        {
            // now _speak started!
            Console.WriteLine("_reader_SpeakStarted\t" + e.ToString());
           // string textContent=????
          //  updateGUI(textContent);

        }


_reader.SpeakAsync("Hello world A B C"); //asynchronize method!!!
_reader.SpeakAsync("Hello world B C D");
_reader.SpeakAsync("Hello world C D E");

问题:

在 SpeakStarted 事件中,无法说出要说出的文本内容。

奇怪的是,“Hello world xx x”确实出现在参数中,如果你在那里放一个断点,但没有办法访问它。

如果有人可以帮助我,我将不胜感激。

.Net 4,Windows 7 64 位,VS2010

4

1 回答 1

1

提示对象并不总是包含文本,这就是它不作为公共属性公开的原因。也可以使用标记或音频文件构建相同的对象。执行此操作的最佳方法是将传递给 SpeakAsync 方法的值存储为全局参数,当您想要显示它们时可以将其传递给 UI。

私有静态字符串_spokenWords;

    static void Main(string[] args)
    {

        SpeechSynthesizer _reader = new SpeechSynthesizer();

        _reader.SpeakStarted += ReaderSpeakStarted;

        _spokenWords = "Hello world A B C";
        _reader.SpeakAsync(_spokenWords); //asynchronize method!!! 


    }


    static void ReaderSpeakStarted(object sender, SpeakStartedEventArgs e)
    {
        // now _speak started! 
        Console.WriteLine("_reader_SpeakStarted\t" + _spokenWords);

        // string textContent=???? 
        //  updateGUI(textContent); 

您还可以查看使用反射来分解提示对象中的私有文本字段以访问该值。尽管这将更加耗费资源并且不一定稳定:

静态无效主要(字符串[] args){

        SpeechSynthesizer _reader = new SpeechSynthesizer();

        _reader.SpeakStarted += ReaderSpeakStarted;

        _reader.SpeakAsync("Hello world A B C"); //asynchronize method!!! 
        _reader.SpeakAsync("Hello world B C D"); 
        _reader.SpeakAsync("Hello world C D E"); 

    }


    static void ReaderSpeakStarted(object sender, SpeakStartedEventArgs e)
    {
        // now _speak started! 
        var spokenWord = GetTextFieldValue(e.Prompt);
        Console.WriteLine("_reader_SpeakStarted\t" + spokenWord);

        // string textContent=???? 
        //  updateGUI(textContent); 

    }

    private static string GetTextFieldValue(Prompt p)
    {
        var text = typeof(Prompt).GetField("_text", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(p);
        return (string)(text.GetType() == typeof(String) ? text : string.Empty);
    }
于 2012-08-13T05:21:19.587 回答