WP7文本到语音一次播放整个集合

时间:2014-01-28 02:59:58

标签: c# windows-phone-7 text-to-speech

我在使用具有文字转语音功能的Windows Phone 7应用程序上工作。我正在使用Text-To-Speech with Microsoft Translator Service和以下C#代码......

// Text-To-Speech with Microsoft Translator Service (http://translatorservice.codeplex.com/)
private void TextToSpeech_Play(object sender, EventArgs e)
{
    SpeechSynthesizer speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
    //string content = "This is a beautiful day!";
    string language = "en";
    //speech.SpeakAsync(content, language);

    foreach (UIElement element in todayschapter.Children)
    {
        if (element is TextBlock)
        {
            string content = (element as TextBlock).Text;
            speech.SpeakAsync(content, language);
        }
    }
}

在这个例子中,todayschapter是一个StackPanel,它的Children是TextBlocks。我想连续播放每个TextBlock的音频。问题是它同时播放每个TextBlock的音频。

我怀疑这个问题是SpeakAsync(),但我不确定。 documentation显示Speak(),但在Visual Studio方法帮助程序下拉列表中不可用(可能是不同的版本)(在您键入时显示的小东西 - 不确定它的名称)。

有没有办法让它在下一场比赛之前等待每场比赛结束? foreach不是正确的选择吗?

与往常一样,如果我的代码看起来很愚蠢,请推荐更好的方法。我是一名初学程序员。

2 个答案:

答案 0 :(得分:2)

只需使用Speak而不是异步调用,因为无论如何都希望一个接一个地使用它。

答案 1 :(得分:0)

SpeakAsync电话确实是问题所在。很遗憾,由于SpeakAsync未返回Task,因此您无法将其转换为await SpeakAsync()(这将是最直接的转换)。

而且,查看源代码,它不会触发事件来判断它何时完成。所以让我们添加一个(在SpeechSynthesizer.cs中):

    public event EventHandler<SpeechEventArgs> SpeakCompleted;

    public void SpeakAsync(string text, string language)
    {
        this.GetSpeakStreamAsyncHelper(text, language, result =>
        {
            if (result.Error == null)
            {
                SoundEffect effect = SoundEffect.FromStream(result.Stream);
                FrameworkDispatcher.Update();
                effect.Play();
                this.OnSpeakCompleted(new SpeechEventArgs(result.Error));            // added to call completion handler
            }
            else
            {
                this.OnSpeakFailed(new SpeechEventArgs(result.Error));
            }
        });
    }
// new function
    private void OnSpeakCompleted(SpeechEventArgs e)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            if (SpeakCompleted != null)
                SpeakCompleted(this, e);
        });
    }

现在,您需要处理SpeakCompleted事件并开始说下一个字符串。

这样的东西(我甚至没有编译过这个,所以要警告):

private Queue<string> utterances;
private SpeechSynthesizer speech;
private void TextToSpeech_Play(object sender, EventArgs e)
{
    speech = new SpeechSynthesizer(CLIENT_ID, CLIENT_SECRET);
    speech.SpeechCompleted += new EventHandler<SpeechEventArgs>(TextToSpeech_Completed); 

    foreach (UIElement element in todayschapter.Children)
    {
        if (element is TextBlock)
        {
            string content = (element as TextBlock).Text;
            utterances.Enqueue(content);
        }
    }
    TextToSpeech_Completed(null, null);   // start speaking the first one
}

private void TextToSpeech_Completed(object sender, SpeechEventArgs e)
{
     if (utterances.Any())
     {
         string contents = utterances.Dequeue();
         speech.SpeakAsync(contents);
     }
}