Vb.net Microsoft语音。合成异步语音不是异步的
晚上好。我尝试使用一个简单的延迟来实现混响效果,但是代码不会继续执行,尽管使用了SpeakAsync方法 我在任何地方都找不到关于这个问题的文档,所以我非常感谢任何人提供的提示。谢谢你抽出时间! 我正在Visual Studio 2017中使用System.Speech 4.0.0版。 我的目标是运行时4.5.2Vb.net Microsoft语音。合成异步语音不是异步的,vb.net,text-to-speech,speech-synthesis,Vb.net,Text To Speech,Speech Synthesis,晚上好。我尝试使用一个简单的延迟来实现混响效果,但是代码不会继续执行,尽管使用了SpeakAsync方法 我在任何地方都找不到关于这个问题的文档,所以我非常感谢任何人提供的提示。谢谢你抽出时间! 我正在Visual Studio 2017中使用System.Speech 4.0.0版。 我的目标是运行时4.5.2 Imports System.Speech.Synthesis Imports System.Threading Imports System.Threading.Tasks Mod
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
中,它似乎将speak操作排队。因此,即使演讲以异步方式开始,一次也只能播放一个
这是我进入反编译程序集之前所做的工作,我认为这是必须进行的:
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)顺序将只对输出进行排队,并且语音不会重叠。
混响效应是一种回声效应,其中快波在短延迟内合并在一起。因此,要产生混响效果,可以产生两个或多个相同的声音,每个声音之间都有延迟。
Reverb()
方法将调用两次OutSpeech()
,设置一个精确的延迟(100ms似乎可以得到结果)。OutSpeech()
方法变为异步方法,因此在创建新合成器时调用将重叠。创建了两个任务。一个用于设置延迟,另一个用于(a)在合成器“讲话”时等待,测试
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
顺便说一句,在您的问题中,您引用的是
MicrosoftSpeech
,但您的代码使用的是System.Speech
。这是两个不同的程序集,您应该对此更加具体。您不能使用块将SpeechSynthesizer
放在中,因为它在声音播放之前就被处理掉了。@Crowcoder您错过了等待任务。运行(Sub(),而(…)
我说的是“您也可以…SpeechHolder.Dispose()不再需要了”编辑。也许我误解了,但如果我误解了,那么OP也可能。@Crowcoder你的意思是我应该更明确地描述为什么不再需要了?我没有尝试你的代码,我只是在谈论我的代码。我现在明白了你的意思,你是如何在时使用合成器的状态的。
。如果你不仔细阅读(像我一样)然后,您可以使用
示例误解您所说的的意思。
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