為了方便調用暫停、繼續的方法。要將speech的功能寫成一個類。直接附上代碼:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Speech.Synthesis;
5 using System.Text;
6 using System.Speech;
7
8 namespace WindowsFormsApplication1
9 {
10 public class TextToSpeak
11 {
12 //想要實現暫停等功能,要調用朗讀時使用的SpeechSynthesizer對象
13 SpeechSynthesizer speech = new SpeechSynthesizer();
14
15 /// <summary>
16 /// 朗讀
17 /// </summary>
18 /// <param name="text">文本</param>
19 /// <param name="rate">語速</param>
20 public void Speak(string text, int rate)
21 {
22 speech.Rate = rate;
23 speech.Speak(text);
24 speech.Dispose();
25 }
26
27 /// <summary>
28 /// 朗讀
29 /// </summary>
30 /// <param name="text">文本</param>
31 /// <param name="rate">語速</param>
32 /// <param name="gender">性別</param>
33 public void Speak(string text, int rate, string gender)
34 {
35
36 speech.Rate = rate;
37 try
38 {
39 if (gender.ToLower() == "male")
40 {
41 speech.SelectVoice("VW Paul");
42 }
43 else if (gender.ToLower() == "female")
44 {
45 speech.SelectVoice("VW Kate");
46 }
47
48 }
49 //這個異常是語音庫未安裝
50 catch (ArgumentException)
51 {
52
53 throw;
54 }
55 finally
56 {
57 speech.Speak(text);
58 speech.Dispose();
59 }
60 }
61
62 /// <summary>
63 /// 保存音頻文件
64 /// </summary>
65 /// <param name="path">路徑</param>
66 /// <param name="text">文本</param>
67 /// <param name="rate">語速</param>
68 /// <param name="gender">性別,可為null</param>
69 public void SaveWaveFile(string path, string text, int rate, string gender)
70 {
71 speech.Rate = rate;
72 try
73 {
74 if (gender.ToLower() == "male")
75 {
76 speech.SelectVoice("VW Paul");
77 }
78 else if (gender.ToLower() == "female")
79 {
80 speech.SelectVoice("VW Kate");
81 }
82
83 }
84 catch (ArgumentException)
85 {
86
87 throw;
88 }
89 finally
90 {
91 speech.SetOutputToWaveFile(path);
92 speech.Speak(text);
93 speech.SetOutputToNull();
94 }
95 }
96
97 public void SpeakPause()
98 {
99 speech.Pause();
100 }
101
102 public void SpeakResume()
103 {
104 speech.Resume();
105 }
106
107 public void SpeakStop()
108 {
109 speech.Dispose();
110 }
111 }
112 }
我使用的是winfrom實現這個類的。一開始想都沒想直接給按鈕加上click事件,調用TextToSpeak類的Speak方法,給另一個按鈕添加SpeakPause功能。運行時復制了好幾段英文,發現窗體出現假死,但是依然有聲音輸出,這叫我怎麼暫停嘛,有點小凌亂。想想這情況應該類似於多線程,不要笑話我,winfrom沒怎麼弄過,之前一直搞的時asp.net。在網上搜了下進度條的實現方法,最後定下來使用backgroundWorker,不因為別的,就是看著別人寫的比較方便~~~
簡單介紹下backgroundWorker吧。它就在工具欄裡躺著。它有好幾個方法。
1. 這個就是後台運行的進程 backgroundWorker1_DoWork(objectsender,DoWorkeventArgs e)。在這裡就放extToSpeak類的Speak方法。它用backgroundWorker1.RunWokerAsync(參數,可不加)來調用。所以就把這個方法放到播放按鈕的click事件裡咯。
2.backgroundWorker1_ProgressChanged這個是運行時可以執行的方法。用backgroundWorker1.ReportProgress(int)調用。
3.backgroundWorker1_RunWorkerCompleted這個是進程結束時執行的。
具體的請看:http://www.cnblogs.com/inforasc/archive/2009/10/12/1582110.html
我是直接在winfrom裡放了個richtextbox,用來寫入要讀的英文。一開始我想當然在backgroundWorker1_DoWork(objectsender,DoWorkeventArgs e)裡的speak中,直接把richtextbox.text的值傳進去,但運行時沒有一點反應。一開始不懂哪錯了,一點一點的試。後台代碼不好調哇,又不能直接調試到代碼,只能用個提示語句來幫忙了。最後才發現是卡在richtextbox.text,它讀取不到這個值。好像是啥原因的~~~但為啥我那個語速的插件值能讀到呢,就因為它是int型麼。。那怎麼辦呢,只能在click事件裡調用時傳參啦。我有兩個參數,一個是text一個是性別,那就string數組了。
上代碼:
1 _ttSpeak = new TextToSpeak();
2 string[] parameter = { richTextBox1.Text, cbbsex.Text };
3 backgroundWorker1.RunWorkerAsync(parameter);
細心的小伙伴應該發現了_ttSpeak = new TextToSpeak(),這個實例化語句怪怪的。其實和TextToSpeak類似,都是把實例化的類對象聲明為成員變量。為啥這裡要重新實例化呢,一開始我也沒注意。運行程序時,第二次點朗讀按鈕時沒反應了。原來是第一次運行時已經把Synthesis的資源釋放了。所以要重新實例化一個,即重寫成員變量。
之後想要使用暫停、繼續功能就很方便了。
1 _ttSpeak.SpeakPause();
_ttSpeak.SpeakResume();
還有個注意點,在執行朗讀功能是要把朗讀按鈕禁用,否則在執行時再click就會報錯哦,等運行結束後再啟用。
就是把啟用的方法寫在backgroundWorker1_RunWorkerCompleted裡就行啦~~~