可以让SpeechSynthesizer以异步方式说出文本,例如:
Private WithEvents _Synth As New SpeechSynthesizer
Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
_Synth.SpeakAsync(New Prompt(Me.TextBox1.Text))
End If
End Sub
SpeechSynthesizer
生成的事件使我们能够分辨计算机语音在说什么。
例如,您可以通过选择以下字符来可视化语音输出:
Private Sub _Synth_SpeakProgress(sender As Object, e As SpeakProgressEventArgs) Handles _Synth.SpeakProgress
Me.TextBox1.SelectionStart = e.CharacterPosition
Me.TextBox1.SelectionLength = e.CharacterCount
End Sub
但是,当反复调用SpeakAsync
时(例如,当我们告诉SpeechSyntesizer
在当前正在讲话时说相同的文本)时,语音请求将排队,并且{{1} }一一播放。
但是,我无法找出合成器当前正在发出哪个请求。 SpeechSynthesizer
不显示this:
使用SAPI5,事件提供了StreamNumber
:
SpeakProgressEventArgs
使用此StreamNumber,您总是可以分辨出SpeechSynthesizer正在播放/讲话的声音。
System.Speech.Synthesis实现是SAPI5实现的现代版本。
但是,我只是找不到StreamNumber指示符或类似信息。
System.Speech.Synthesis仅提供有关正在发生的所有事情的信息,因此它不太可能不提供仅在处理哪些请求的信息。
如何检索?
答案 0 :(得分:1)
要阐明我对使用Prompt Class保留所需的任何身份证明状态的评论,请考虑以下内容,其中Prompt
拥有对源TextBox
的引用。
Imports System.Speech.Synthesis
Public Class MyPrompt : Inherits Prompt
Private tbRef As WeakReference(Of TextBox)
Public Sub New(textBox As TextBox)
MyBase.New(textBox.Text)
' only hold a weak reference to the TextBox
' to avoid any disposal issues
tbRef = New WeakReference(Of TextBox)(textBox)
End Sub
Public ReadOnly Property SourceTextBox As TextBox
Get
Dim ret As TextBox = Nothing
tbRef.TryGetTarget(ret)
Return ret
End Get
End Property
End Class
现在您的原始代码可以写为:
Imports System.Speech.Synthesis
Public Class Form1
Private WithEvents _Synth As New SpeechSynthesizer
Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
' use a custom prompt to store the TextBox
_Synth.SpeakAsync(New MyPrompt(Me.TextBox1))
End If
End Sub
Private Sub _Synth_SpeakProgress(sender As Object, e As SpeakProgressEventArgs) Handles _Synth.SpeakProgress
Dim mp As MyPrompt = TryCast(e.Prompt, MyPrompt)
If mp IsNot Nothing Then
Dim tb As TextBox = mp.SourceTextBox
If tb IsNot Nothing Then
' set the selection in the source TextBox
tb.SelectionStart = e.CharacterPosition
tb.SelectionLength = e.CharacterCount
End If
End If
End Sub
End Class
编辑:
OP希望将其与SpeakSsmlAsync method一起使用。这本身是不可能的,因为该方法使用Prompt(String, SynthesisTextFormat) Constructor创建基数Prompt
并在调用Prompt
之后返回创建的SpeechSynthesizer.SpeakAsync(created_prompt)
。
下面是派生的Prompt
类,它接受ssml字符串或PromptBuilder instance以及整数标识符。
一个新版本的MyPrompt使用ssml和一个整数标识符。
Imports System.Speech.Synthesis
Public Class MyPromptV2 : Inherits Prompt
Public Sub New(ssml As String, identifier As Int32)
MyBase.New(ssml, SynthesisTextFormat.Ssml)
Me.Identifier = identifier
End Sub
Public Sub New(builder As PromptBuilder, identifier As Int32)
MyBase.New(builder)
Me.Identifier = identifier
End Sub
Public ReadOnly Property Identifier As Int32
End Class
...
Imports System.Speech.Synthesis
Public Class Form1
Private WithEvents _Synth As New SpeechSynthesizer
Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
' build some ssml from the text
Dim pb As New PromptBuilder
pb.AppendText(TextBox1.Text)
' use ssml and and integer
_Synth.SpeakAsync(New MyPrompt(pb.ToXml, 10))
' or
'_Synth.SpeakAsync(New MyPrompt(pb, 10))
End If
End Sub
Private Sub _Synth_SpeakProgress(sender As Object, e As SpeakProgressEventArgs) Handles _Synth.SpeakProgress
Dim mp As MyPromptV2 = TryCast(e.Prompt, MyPromptV2)
If mp IsNot Nothing Then
Select Case mp.Identifier
Case 10
TextBox1.SelectionStart = e.CharacterPosition
TextBox1.SelectionLength = e.CharacterCount
End Select
End If
End Sub
End Class
答案 1 :(得分:0)
还有另一种获取当前正在处理的句子的方法。您可以为句子分配选择编号,然后通过获取该句子的索引来识别语音。您可以进一步处理条件。使用SpeechRecognizedEventArgs
方法的SpeechRecognized
自变量获取句子索引。
void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
string txt = e.Result.Text;
int sentenceIndex = txt.IndexOf("My Sentence");
if (sentenceIndex >= 0)
{
Console.WriteLine("Currently Speaking Sentence: My Sentence, with index number: "
+ sentenceIndex);
}
//.... some code here
}
遵循完整的示例here。
编辑1:
类范围
SpeechSynthesizer
对象为应用程序提供了说话的能力。SpeechRecognitionEngine
对象允许应用程序侦听和识别口语单词或短语。