.NET 對英文語音支援良好,但中文語音支援未內建。需安裝 Microsoft Speech Application SDK (SASDK),最新版 SAPI 5.1 支援中、日、英三種語言。下載位址:https://www.microsoft.com/speech/download/sdk51/,需安裝 Speech SDK 5.1 與 5.1 Language Pack(可選擇支援語言)。
安裝完成後,在專案參考中加入 SAPI.dll(透過「加入參考」對話框 COM 標籤選取 Microsoft Speech Object Library)。
public class Speach
{
private static Speach _Instance = null;
private SpeechLib.SpVoiceClass voice = null;
private Speach() { BuildSpeach(); }
public static Speach Instance()
{
if (_Instance == null) _Instance = new Speach();
return _Instance;
}
private void SetChinaVoice()
{
voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0);
}
private void SetEnglishVoice()
{
voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(1);
}
private void SpeakChina(string strSpeak) { SetChinaVoice(); Speak(strSpeak); }
private void SpeakEnglish(string strSpeak) { SetEnglishVoice(); Speak(strSpeak); }
public void AnalyseSpeak(string strSpeak)
{
int iCbeg = 0, IEbeg = 0;
bool IsChina = true;
for (int i = 0; i < strSpeak.Length; i++)
{
char chr = strSpeak[i];
if (IsChina)
{
if (chr <= 122 && chr >= 65) // ASCII 英文字元範圍
{
int iLen = i - iCbeg;
string strValue = strSpeak.Substring(iCbeg, iLen);
SpeakChina(strValue);
IEbeg = i; IsChina = false;
}
}
else
{
if (chr > 122 || chr < 65) // 非 ASCII 英文視為中文
{
int iLen = i - IEbeg;
string strValue = strSpeak.Substring(IEbeg, iLen);
SpeakEnglish(strValue);
iCbeg = i; IsChina = true;
}
}
}
// 處理剩餘段落
if (IsChina)
{
int iLen = strSpeak.Length - iCbeg;
SpeakChina(strSpeak.Substring(iCbeg, iLen));
}
else
{
int iLen = strSpeak.Length - IEbeg;
SpeakEnglish(strSpeak.Substring(IEbeg, iLen));
}
}
private void BuildSpeach()
{
if (voice == null) voice = new SpVoiceClass();
}
public int Volume
{
get { return voice.Volume; }
set { voice.SetVolume((ushort)value); }
}
public int Rate
{
get { return voice.Rate; }
set { voice.SetRate(value); }
}
private void Speak(string strSpeack)
{
try { voice.Speak(strSpeack, SpeechVoiceSpeakFlags.SVSFlagsAsync); }
catch (Exception err) { throw new Exception("發生一個錯誤:" + err.Message); }
}
public void Stop()
{
voice.Speak(string.Empty, SpeechLib.SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
}
public void Pause() { voice.Pause(); }
public void Continue() { voice.Resume(); }
}
AnalyseSpeak 以 ASCII 碼 (65-122) 區分英文字元,實現中英文混合自動切換語種朗讀。Volume/Rate 屬性封裝底層 SetVolume/SetRate。Speak 採非同步旗標 SVSFlagsAsync,不阻塞 UI 執行緒。Stop/Pause/Continue 播放控制。