在.net中使用語音識別和語音合成技術,需要藉助微軟的Speech SDK,如果是要在Web應用程序中使用,則需要Speech Application SDK。其中Speech SDK可以在http://www.microsoft.com/speech/download/sdk51/下載,其中有兩個文件Speech SDK 5.1和5.1 Language Pack,前者是開發包,但是其中只包含對英文的支持,後者是中文和日文的語言包,裝完就能支持中文了。
SDK組成結構
演練
1. 打開vs2005,建立一個windows application,在設計窗體中加入一個label,一個richtextbox(用於輸入要讀的文本),以及一個button。並分別設置的label與button的Text屬性。如下圖
2. 添加必要的引用,項目->添加引用->COM選擇Microsoft Speech Object Library點確定退出。
3. 雙擊button,爲其添加事件。在代碼頁頂端先添加命名空間,代碼如
using SpeechLib;
4.
button的事件處理程序代碼如下。
private void button1_Click(object sender, EventArgs e)
{
//SpVoiceClass voice = new SpVoiceClass();//SAPI 5.1
SpVoice voice = new SpVoice();//SAPI 5.4
voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0); //其中3爲中文,024爲英文
voice.Speak(richTextBox1.Text,SpeechVoiceSpeakFlags.SVSFDefault);
}
5. 按F5運行,在空白區域輸入文字,點朗讀,試試效果吧。
SpVoiceClass詳解
屬性 |
描述 |
AlertBoundary |
取得或設置停頓分界線。 |
AllowAudioOutputFormatChangesOnNextSet |
設置是否允許聲音自動調整到合適狀態以適應其音頻輸出。 |
AudioOutput |
.取得或設置當前聲音使用的的音頻輸出對象 |
AudioOutputStream |
取得或設置當前聲音使用的的音頻輸出流對象。 |
EventInterests |
取得或設置當前聲音返回的事件類型。 |
Priority |
取得或設置聲音的優先級。 |
Rate |
取得或設置閱讀的速度。 |
Status |
返回一個ISpeechVoiceStatus 對象用於顯示當前閱讀和事件的狀態 |
SynchronousSpeakTimeout |
取得或設置一個時間間隔,用於標識多久未獲得一個輸出設備後,一個同步的Speak 和SpeakStream將終止,以毫秒計算。 |
Voice |
取得或設置發音對象。 |
Volume |
取得或設置聲音的大小 。 |
方法 |
描述 |
DisplayUI |
是否在控制面板中展示詳細設置。 |
GetAudioOutputs |
返回一個可用的音頻輸出標記。 |
GetVoices |
返回一個可用的發音對象。 |
IsUISupported |
決定是否能通過控制棉板的音頻設置來控制。 |
Pause |
暫停朗讀。. |
Resume |
恢復暫停,繼續播放。 |
Skip |
在當前輸入的文本流中向前或向後跳一定距離再播放。 |
Speak |
閱讀一個字符串。 |
SpeakCompleteEvent |
得到一個朗讀完畢的時間句柄 |
SpeakStream |
朗讀一個文本流或一個聲音文件。 |
WaitUntilDone |
阻塞進程,直到聲音播放完畢或者超時。 |
介紹了關於語音合成的一些基礎知識,就是先j建立一個SpVoiceClass類的對象,然後調用對象的GetVoices方法取的一個發音的對象,但是通過設置該方法的參數只能建立中文發音或是英文發音的對象,而對於中英文混合的文本卻沒有辦法。爲解決這個問題,可以對字符串中的每的字符的ASC碼進行判斷,進而分辨傳入的字符串是中文還是英文。以下是判斷的代碼。
{
int iCbeg = 0 ;
int iEbeg = 0 ;
bool IsChina = true ;
for(int i=0;i<strSpeak.Length;i++)
{
char chr = strSpeak[i] ;
if (IsChina)
{
if (chr<=122&&chr>=65)
{
int iLen = i - iCbeg ;
string strValue =
strSpeak.Substring(iCbeg,iLen) ;
SpeakChina(strValue) ;
iEbeg = i ;
IsChina = false ;
}
}
else
{
if (chr>122||chr<65)
{
int iLen = i - iEbeg ;
string strValue = strSpeak.Substring(iEbeg,iLen) ;
this.SpeakEnglishi(strValue) ;
iCbeg = i ;
IsChina = true ;
}
}
}
return IsChina;
}
對於Speak方法的參數,第一個是一個字符串類型,第二個是一個SpeechVoiceSpeakFlags類型的枚舉。當將其設置爲SVSFDefault時,則第一個就是要讀的文本,若將其設置爲SVSFIsFilename
時,第一個參數就是所要讀的文本的文件名,而不是要讀的內容。
下面介紹這個類的SpeakStream方法,這個方法有2個參數,第一個是SpeechBaseStream,第二和Speak一樣,是一個SpeechVoiceSpeakFlags類型的枚舉。SpeechBaseStream是一個接口,繼承它的有3個對象,這3個都很相似,先介紹其中之一SpFileStream。SpFileStream有3個比較常用的方法:Read,Seek,Write。其中Read方法可以創建一個*.wav文件,以下代碼演示了創建文件的步驟:
SpVoiceClass v = new SpVoiceClass();
fs1.Open(textBox1.Text, SpeechStreamFileMode.SSFMCreateForWrite, false);
//textBox1.text是要創建的文件的路徑。
v.AudioOutputStream = fs1;
string[] ss = new string[4] { "this", "is", "a", "demo" };
foreach (string s in ss)
{
v.Speak(s, SpeechVoiceSpeakFlags.SVSFlagsAsync);
}
fs1.Close();
下面的代碼將用於展示Speak與SpeakStream:
SpFileStreamClass fs1 = new SpFileStreamClass();
SpFileStreamClass fs2 = new SpFileStreamClass();
SpVoiceClass v = new SpVoiceClass();
fs1.Open(textBox1.Text, SpeechStreamFileMode.SSFMOpenForRead, false);
fs2.Open(textBox2.Text, SpeechStreamFileMode.SSFMOpenForRead, false);
v.Speak("This is the first sound file", SpeechVoiceSpeakFlags.SVSFlagsAsync);
v.SpeakStream(fs1, SpeechVoiceSpeakFlags.SVSFlagsAsync);
v.Speak("This is the second sound file", SpeechVoiceSpeakFlags.SVSFlagsAsync);
v.SpeakStream(fs2, SpeechVoiceSpeakFlags.SVSFlagsAsync);
fs1.Close();
fs2.Close();