Microsoft Speech.Synthesis 异步语音不是异步的

Microsoft Speech.Synthesis Async speech not Asynchronous

晚上好。我正在尝试使用简单的延迟来实现混响效果,但尽管使用了 SpeakAsync 方法,代码仍无法继续执行。

我在任何地方都找不到关于这个问题的文档,所以我非常感谢您提供的任何提示。感谢您的时间! 我在 Visual Studio 2017 年使用 System.Speech 版本 4.0.0。 我的目标是运行时 4.5.2

Imports System.Speech.Synthesis
Imports System.Threading
Imports System.Threading.Tasks

Module Module1

Sub main()
    Dim SpeechString As String = "This is a test phrase, there are many 
like it, but this one is mine."
    Call OutSpeech(1, 100, SpeechString)

End Sub


Sub OutSpeech(SpeechRate As Integer, SpeechVolume As Integer, SpeechText As String)
    Dim SpeechHolder As New SpeechSynthesizer

    SpeechHolder.Rate = SpeechRate
    SpeechHolder.Volume = SpeechVolume
    SpeechHolder.SpeakAsync(SpeechText)
    Thread.Sleep(100)
    SpeechHolder.SpeakAsync(SpeechText)
    Console.ReadLine()
End Sub

模块结束

深入研究 System.Speech.dll 它似乎在排队发言操作。因此,尽管演讲将异步开始,但一次只会播放一个。

这是我进入反编译程序集之前我认为这是必须发生的事情:

private void AddSpeakParameters(VoiceSynthesis.Parameters param)
{
    lock (this._pendingSpeakQueue)
    {
        this._pendingSpeakQueue.Enqueue(param);
        if (this._pendingSpeakQueue.Count == 1)
        {
            this._evtPendingSpeak.Set();
        }
    }
}

您可以使用 SpeechSynthesizer 的多个实例来同时播放声音或根据您的睡眠进行补偿。

按顺序调用 SpeechHolder.SpeakAsync(SpeechText) 只会对输出进行排队,Speech(es) 不会重叠。

混响效果是一种回声效果,其中快波在短暂的延迟中合并在一起。因此,要获得类似混响的效果,请生成两个或多个相同的声音,每个声音之间都有延迟。

Reverb() 方法将调用两次 OutSpeech(),设置一个适当的延迟(100 毫秒似乎适合获得结果)。

Sub Reverb()
  Dim Delay As Integer = 100
  Dim SpeechString As String = "This is a test phrase, there are many like it, but this one is mine."
  OutSpeech(1, 100, Delay, SpeechString)
  OutSpeech(1, 100, Delay, SpeechString)

End Sub

OutSpeech() 方法变为异步方法,因此在创建新合成器时调用会重叠。
创建了两个任务。一个用于设置延迟,一个用于 (a) 等待合成器 "speaking",测试 SpeechHolder.State.

Async Sub OutSpeech(SpeechRate As Integer, SpeechVolume As Integer, Delay As Integer, SpeechText As String)
    Using SpeechHolder As SpeechSynthesizer = New SpeechSynthesizer
        SpeechHolder.Rate = SpeechRate
        SpeechHolder.Volume = SpeechVolume

        Await Task.Run(Async Function() As Task(Of Boolean)
                       SpeechHolder.SpeakAsync(SpeechText)
                       Await Task.Delay(Delay)
                       Await Task.Run(Sub()
                                          While SpeechHolder.State = SynthesizerState.Speaking
                                          End While
                                      End Sub)
                       Return True
                   End Function)
    End Using
End Sub