我超愛看小說,由於長時間盯著電腦眼睛疼,所以從網上下載了一款《讀書狼》的軟體。雖然達不到真人念書的水平,但是為了保護寶貴的眼睛,這也算是不錯的了。然後自己想做一個類似的小工具。而且要是可以的話,可以在生產車間的序列碼、註冊編號等輸入的時候加入語音檢測,這樣可以防止眼睛疲勞導致的錯誤。
首先,要安裝Microsoft Speech SDK,可以從微軟網站上下載,我安裝的是SAPI 5.1。安裝完畢以後,會附帶chm格式的開發文檔。
建立一個C# Winform程式,拖一個RichTextBox控制項,添加兩個啟停按鈕。介面可以自己做,我的介面如下所示:
設定朗讀屬性的介面如下:
在工程中添加應用:SpeechLib,具體方法是添加引用->COM->Microsoft Speech Object Library 5.0.
SpVoiceClass是朗讀的函數,這個函數可以控制是同步朗讀還是非同步朗讀,我在這裡選擇了是非同步朗讀。朗讀的聲音包括英文、中文、日文等,需要安裝中文等語音庫。這些也可以在微軟的網站上找到。SpVoiceClass還可以控制是哪個聲音朗讀,朗讀的語速、音量等屬性。非同步朗讀還有一個問題就是當朗讀完畢的時候控制按鈕狀態的恢複。另外說明:英文版的作業系統和中文版的作業系統中朗讀聲音的排序是不一樣的,其他文章說0代表中文,請不要武斷這麼認為,在英文作業系統中,0是代表了英文,為了保險起見,可以讀取系統中所有的語音列舉到組合框以供選擇。下面是主要的代碼:
public partial class MainForm : Office2007Form { bool bStop; // 是否停止 bool bPause; // 是否暫停 private Preference ThePreference = new Preference(); // 配置類 SpVoiceClass SpeechInstance = new SpVoiceClass(); // 朗讀類 public MainForm() { this.ThePreference.Init(); InitializeComponent(); // 自訂事件-配置修改後立即更新 this.ThePreference.Invalidate += new Preference.InvalidateHandler(InvalidateSpeechCfg); bStop = true; // 初始停止 bPause = false; // 初始沒有暫停 } private void MainForm_Load(object sender, EventArgs e) { // 配置語音、語速和音量 this.SpeechInstance.Voice = this.SpeechInstance.GetVoices(string.Empty, string.Empty).Item(this.ThePreference.SpeechConfig.Type); this.SpeechInstance.Rate = this.ThePreference.SpeechConfig.Rate; this.SpeechInstance.Volume = this.ThePreference.SpeechConfig.Volume; // 非同步模式下,朗讀完畢的事件處理 this.SpeechInstance.EndStream += new SpeechLib._ISpeechVoiceEvents_EndStreamEventHandler(FuncEndStream); } private void FuncEndStream(int i, object o) { bStop = true; UpdateIcon_playpause(); } /// <summary> /// 開始閱讀和暫停按鈕 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void toolStripButton_play_pause_Click(object sender, EventArgs e) { if (bStop == true) { if (this.richTextBox.Lines.Length == 0) { bStop = true; } else { ReadTextInControl(this.richTextBox.Text); if (bPause == true) // 此處一定要有這個判斷,因為從Pause狀態直接調用Speak函數,不會朗讀,除非Resume { SpeechInstance.Resume(); bPause = false; } bStop = false; } } else { if (bPause == true) { bPause = false; SpeechInstance.Resume(); } else { bPause = true; SpeechInstance.Pause(); } bStop = true; } UpdateIcon_playpause(); } private void UpdateIcon_playpause() { if (bStop == true) { this.toolStripButton_play_pause.Image = ReadFish.Properties.Resources.Play; } else { if (bPause == true) { this.toolStripButton_play_pause.Image = ReadFish.Properties.Resources.Play; } else { this.toolStripButton_play_pause.Image = ReadFish.Properties.Resources.Pause; } } } public void ReadTextInControl(string strRead) { SpeechInstance.Speak(strRead, SpeechVoiceSpeakFlags.SVSFlagsAsync); // 非同步朗讀 } private void toolStripButton_stop_Click(object sender, EventArgs e) { if (bStop == false) { SpeechInstance.Speak(string.Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak); // 結束朗讀 bStop = true; } UpdateIcon_playpause(); } private void InvalidateSpeechCfg(object sender, EventArgs e) { this.SpeechInstance.Voice = this.SpeechInstance.GetVoices(string.Empty, string.Empty).Item(this.ThePreference.SpeechConfig.Type); this.SpeechInstance.Rate = this.ThePreference.SpeechConfig.Rate; this.SpeechInstance.Volume = this.ThePreference.SpeechConfig.Volume; }}
下面是擷取和設定語音列表的函數實現
cb_type.Items.Clear(); SpeechLib.SpVoice voice = new SpeechLib.SpVoice(); int i = 0; foreach (SpeechLib.ISpeechObjectToken t in voice.GetVoices(string.Empty, string.Empty)) { cb_type.Items.Add(t.GetDescription(i++)); }