System.Speech.Synthesis 的事件信息中的流编号在哪里?
Where is the stream number in the event info for System.Speech.Synthesis?
可以让 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
说出相同的文本时,它正在说话),语音请求被排队,并且 SpeechSynthesizer
一一播放。
但是,我一直没能查明合成器当前在说哪个请求。 SpeakProgressEventArgs
不显示 this:
使用 SAPI5,事件提供了 StreamNumber
:
Parameters
StreamNumber
The stream number which generated the event. When a voice enqueues more than one stream by speaking asynchronously, the stream number is necessary to associate an event with the appropriate stream.
使用这个 StreamNumber,你总能知道 SpeechSynthesizer 正在播放/说话的内容。
System.Speech.Synthesis 实现是 SAPI5 实现的现代版本。
但是,我就是找不到 StreamNumber 指标或类似信息。
System.Speech.Synthesis 提供有关刚刚发生的一切的信息,因此它极不可能不提供它正在处理的请求的信息。
如何找回?
还有另一种方法可以获取当前正在处理的句子。您可以为您的句子分配选择编号,然后您可以通过获取该句子的索引来识别语音;您可以进一步处理条件。使用 SpeechRecognized
方法的 SpeechRecognizedEventArgs
参数获取句子索引。
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:
The class-scope SpeechSynthesizer
object gives the application the ability to speak. The SpeechRecognitionEngine
object allows the application to listen for and recognize spoken words or phrases.
为了澄清我关于使用 Prompt Class 来保存您需要的任何标识状态的评论,请考虑以下内容,其中 Prompt
保存对源 TextBox
.[=23 的引用=]
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 希望在调用 SpeechSynthesizer.SpeakAsync(created_prompt)
.
后将其与 SpeakSsmlAsync method. That in itself is not possible as that method creates a base Prompt
using the Prompt(String, SynthesisTextFormat) Constructor 和 returns 一起使用创建的 Prompt
下面是派生的 Prompt
class,它接受 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
可以让 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
说出相同的文本时,它正在说话),语音请求被排队,并且 SpeechSynthesizer
一一播放。
但是,我一直没能查明合成器当前在说哪个请求。 SpeakProgressEventArgs
不显示 this:
使用 SAPI5,事件提供了 StreamNumber
:
Parameters
StreamNumber
The stream number which generated the event. When a voice enqueues more than one stream by speaking asynchronously, the stream number is necessary to associate an event with the appropriate stream.
使用这个 StreamNumber,你总能知道 SpeechSynthesizer 正在播放/说话的内容。
System.Speech.Synthesis 实现是 SAPI5 实现的现代版本。
但是,我就是找不到 StreamNumber 指标或类似信息。
System.Speech.Synthesis 提供有关刚刚发生的一切的信息,因此它极不可能不提供它正在处理的请求的信息。
如何找回?
还有另一种方法可以获取当前正在处理的句子。您可以为您的句子分配选择编号,然后您可以通过获取该句子的索引来识别语音;您可以进一步处理条件。使用 SpeechRecognized
方法的 SpeechRecognizedEventArgs
参数获取句子索引。
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:
The class-scope
SpeechSynthesizer
object gives the application the ability to speak. TheSpeechRecognitionEngine
object allows the application to listen for and recognize spoken words or phrases.
为了澄清我关于使用 Prompt Class 来保存您需要的任何标识状态的评论,请考虑以下内容,其中 Prompt
保存对源 TextBox
.[=23 的引用=]
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 希望在调用 SpeechSynthesizer.SpeakAsync(created_prompt)
.
Prompt
using the Prompt(String, SynthesisTextFormat) Constructor 和 returns 一起使用创建的 Prompt
下面是派生的 Prompt
class,它接受 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