在用网上下载的例子学习基本操作的基础上,捣鼓了一个晚上,终于实现了调用TTS SDK朗读时获取当前词语的方法(中英文皆可)。

 

 
  
  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.ComponentModel; 
  4. using System.Data; 
  5. using System.Drawing; 
  6. using System.Text; 
  7. using System.Windows.Forms; 
  8. using SpeechLib; //引入语音 
  9. using System.Threading; 
  10. using System.Timers; 
  11.  
  12. namespace JcSpeak 
  13.     public partial class Form1 : Form 
  14.     { 
  15.         Thread mythread; 
  16.         SpeechVoiceSpeakFlags svsf; 
  17.         //这里用的是SpVoice接口来实例化SpVoiceClass类,原来程序中是SpVoiceClass,但是没有Word事件 
  18.         SpVoice svc=null;        
  19.         
  20.         public Form1() 
  21.         { 
  22.             InitializeComponent(); 
  23.         } 
  24.  
  25.         private void Form1_Load(object sender, EventArgs e) 
  26.         { 
  27.             richTextBox1.Text = "可以进行英文朗读;如果您想进行中文朗读,还需要下载并安装这两个文件是必需的,安装完这两个文件后,本程序就能进行中文朗读了。"
  28.             svsf = SpeechVoiceSpeakFlags.SVSFDefault; 
  29.             svc = new SpVoiceClass();          
  30.         } 
  31.  
  32.         //朗读 
  33.         private void Btn_Read_Click(object sender, EventArgs e) 
  34.         { 
  35.             mythread = new Thread(Voice); 
  36.             mythread.Start(); 
  37.             //关键就是这句话了,增加了SpVoice.Word事件,可以在朗读中一直侦听当前朗读的词语 
  38.             svc.Word += new _ISpeechVoiceEvents_WordEventHandler(svc_Word); 
  39.         } 
  40.  
  41.         void svc_Word(int StreamNumber, object StreamPosition, int CharacterPosition, int Length) 
  42.         { 
  43.             richTextBox1.Select(CharacterPosition, Length); 
  44.             richTextBox1.SelectionColor = Color.Blue; 
  45.             throw new NotImplementedException(); 
  46.         } 
  47.  
  48.         private void Voice() 
  49.         { 
  50.             svc.Speak(richTextBox1.Text.Trim(), svsf); 
  51.             mythread.Abort(); 
  52.         } 
  53.  
  54.         //暂停 
  55.         private void Btn_Pause_Click(object sender, EventArgs e) 
  56.         { 
  57.             svc.Pause(); 
  58.         } 
  59.  
  60.         //继续 
  61.         private void Btn_Resume_Click(object sender, EventArgs e) 
  62.         { 
  63.             svc.Resume(); 
  64.         } 
  65.  
  66.         //停止 
  67.         private void Btn_Stop_Click(object sender, EventArgs e) 
  68.         {  
  69.            svc.Speak(string.Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak); 
  70.         } 
  71. }
  72. }
     

简单的效果图

心得:

1、首先是本文的主角,SpVoice中的Word事件。文档中的描述是这样的

 

Microsoft Speech SDK

Speech Automation 5.1


Object: SpVoice (Events)

Word Event

 

The Word event occurs when the text-to-speech (TTS) engine detects a word boundary while speaking a stream for the SpVoice object.

 

SpVoice.Word(      StreamNumber As Long,      StreamPosition As Variant,      CharacterPosition As Long,      Length As Long ) 
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.
StreamPosition
The character position in the output stream at which the word begins.
CharacterPosition
The character position in the input stream one character before the start of the word. In the case of the first word in a stream, this parameter is zero.
Length
The length of the word in the input stream.

英文很烂,就不翻译了。可见,获取当前朗读的词语就是靠CharacterPosition和Length两个参数。

 

2、一直没能解决的是SpVoice的停止问题。很多例子里面都是(包括自己这个)

 
  
  1. svc.Speak(string.Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak); 

但是一点停止按钮程序就死了,幸好暂停功能还是可以用的,只好先用暂停代替着。