基于C#實(shí)現(xiàn)文字轉(zhuǎn)語音功能
好多年前自己研究的了,今天突然翻出來了,記錄下
簡單說明
在C#中,集成了一個(gè)語音對象SpeechSynthesizer。
SpeechSynthesizer可以根據(jù)填入的文字內(nèi)容自動(dòng)解析成語音并使用系統(tǒng)揚(yáng)聲器進(jìn)行語音播報(bào)。
程序說明
支持手動(dòng)輸入文字,轉(zhuǎn)換為語音。
可以調(diào)整語速。
對kv、sf6、.等關(guān)鍵詞進(jìn)行轉(zhuǎn)義(kv-千伏;sf6-六氟化硫;.-點(diǎn))
支持生成語音文件(這個(gè)沒有對關(guān)鍵字進(jìn)行轉(zhuǎn)義)
效果圖

語音試聽實(shí)現(xiàn)
/// <summary>
/// 試聽
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnListen_Click(object sender, EventArgs e)
{
string text = textBox1.Text;
rate = this.cbxRate.SelectedIndex;
if (text.Trim().Length == 0)
{
MessageBox.Show("不能閱讀空內(nèi)容!", "錯(cuò)誤提示");
return;
}
if (btnListen.Text == "語音試聽")
{
speech = new SpeechSynthesizer();
new Thread(Speak).Start();
btnListen.Text = "停止試聽";
}
else if (btnListen.Text == "停止試聽")
{
speech.SpeakAsyncCancelAll();//停止閱讀
btnListen.Text = "語音試聽";
}
}
private void Speak()
{
PromptBuilder builder = GetBuiltPrompt(this.textBox1.Text.ToString().Trim());
speech.Rate = rate;
speech.SelectVoice("Microsoft Huihui Desktop");//設(shè)置播音員(中文)
speech.Volume = value;
speech.SpeakAsync(builder);//語音閱讀方法
speech.SpeakCompleted += speech_SpeakCompleted;//綁定事件
}
private PromptBuilder GetBuiltPrompt(string keywords)
{
//from http://msdn.microsoft.com/msdnmag/issues/06/01/speechinWindowsVista/
//This prompt is quite complicated
//So I'm going to build it first, and then render it.
PromptBuilder myPrompt = new PromptBuilder();
//Start the main speaking style
PromptStyle mainStyle = new PromptStyle();
mainStyle.Rate = PromptRate.NotSet;
mainStyle.Volume = PromptVolume.Medium;
// mainStyle.Emphasis=PromptEmphasis.Reduced;
myPrompt.StartStyle(mainStyle);
convert(myPrompt, keywords);
myPrompt.EndStyle();
return myPrompt;
}
/// <summary>
/// 轉(zhuǎn)義關(guān)鍵字
/// </summary>
private void convert(PromptBuilder myPrompt, string keywords)
{
//判斷是否存在要轉(zhuǎn)換的關(guān)鍵字
Dictionary<int, string> convertCharacter = new Dictionary<int, string>();
var kv_Index = keywords.IndexOf("kV");
var sf6_Index = keywords.IndexOf("SF6");
var point_index = keywords.IndexOf(".");
if (kv_Index > -1)
{
convertCharacter.Add(kv_Index, "kv");
}
if (sf6_Index > -1)
{
convertCharacter.Add(sf6_Index, "sf6");
}
if (point_index > -1)
{
convertCharacter.Add(point_index, ".");
}
convertArray(convertCharacter, myPrompt, keywords);
}
/// <summary>
/// 轉(zhuǎn)義關(guān)鍵字
/// </summary>
private void convertArray(Dictionary<int, string> convertCharacter, PromptBuilder myPrompt, string deviceName)
{
string r = @"[0-9]+";
Regex reg = new Regex(r, RegexOptions.IgnoreCase | RegexOptions.Singleline);//2秒后超時(shí)
MatchCollection mc = reg.Matches(deviceName);//設(shè)定要查找的字符串
//按關(guān)鍵字升序排列
convertCharacter = convertCharacter.OrderBy(t => t.Key).ToDictionary(p => p.Key, o => o.Value);
int hasLen = 0;//記錄已經(jīng)截取的長度
int splitNum = convertCharacter.Count;//要拆分的段數(shù)
//針對有需要轉(zhuǎn)換的地方做特殊處理
if (splitNum > 0)
{
for (var i = 0; i < splitNum; i++)
{
var startIndex = convertCharacter.ElementAt(i).Key;//關(guān)鍵字開始的索引
var keyValue = convertCharacter.ElementAt(i).Value.ToLower();//關(guān)鍵字
var keyLen = keyValue.Length;//關(guān)鍵字對應(yīng)的長度
//先把關(guān)鍵字前面的追加到標(biāo)題
myPrompt.AppendText(deviceName.Substring(hasLen, startIndex - hasLen));
hasLen = startIndex + keyLen;//留做截取不是關(guān)鍵字的長度
//判斷關(guān)鍵字的類型,確定轉(zhuǎn)換方式
if (keyValue == "kv")
{
myPrompt.AppendSsmlMarkup("<say-as interpret-as = \"kV\">千伏</say-as>");
}
else if (keyValue == "sf6")
{
myPrompt.AppendTextWithAlias("SF6", "六氟化硫");
}
else if (keyValue == "-")
{
myPrompt.AppendTextWithHint("-", SayAs.NumberCardinal);
}
else if (keyValue == ".")
{
myPrompt.AppendTextWithAlias(".", "點(diǎn)");
}
//如果循環(huán)到最后一個(gè)關(guān)鍵字,再把最后一個(gè)關(guān)鍵字后邊的數(shù)追加上
if (i == splitNum - 1)
{
myPrompt.AppendText(deviceName.Substring(hasLen));
}
}
}
else
{
myPrompt.AppendText(deviceName);
}
}
/// <summary>
/// 語音閱讀完成觸發(fā)此事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void speech_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
{
//改變按鈕文本值
ChangeBtnText changeBtnText = ChangeText;
this.btnListen.BeginInvoke(changeBtnText);
}
/// <summary>
/// 委托方法,改變按鈕值
/// </summary>
public void ChangeText()
{
btnListen.Text = "語音試聽";
}以上就是基于C#實(shí)現(xiàn)文字轉(zhuǎn)語音功能的詳細(xì)內(nèi)容,更多關(guān)于C#文字轉(zhuǎn)語音的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#實(shí)現(xiàn)生成所有不重復(fù)的組合功能示例
這篇文章主要介紹了C#實(shí)現(xiàn)生成所有不重復(fù)的組合功能,涉及C#數(shù)學(xué)運(yùn)算中組合數(shù)運(yùn)算的相關(guān)原理應(yīng)用操作技巧,需要的朋友可以參考下2017-12-12
詳解WPF雙滑塊控件的使用和強(qiáng)制捕獲鼠標(biāo)事件焦點(diǎn)
這篇文章主要為大家詳細(xì)介紹了WPF中雙滑塊控件的使用和強(qiáng)制捕獲鼠標(biāo)事件焦點(diǎn)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以嘗試一下2022-07-07
Winform學(xué)生信息管理系統(tǒng)各子窗體剖析(3)
這篇文章主要針對Winform學(xué)生信息管理系統(tǒng)各子窗體進(jìn)行剖析,感興趣的小伙伴們可以參考一下2016-05-05
C#實(shí)現(xiàn)Workstation相關(guān)功能過程
本文提供了實(shí)現(xiàn)Workstation功能的C#代碼示例,涵蓋工作站管理、遠(yuǎn)程控制、性能監(jiān)控和定時(shí)任務(wù)等核心模塊,代碼結(jié)構(gòu)清晰,可根據(jù)需要擴(kuò)展,但使用時(shí)需注意網(wǎng)絡(luò)權(quán)限和異常處理2026-05-05
C# TreeView無限目錄樹實(shí)現(xiàn)方法
這篇文章主要介紹了C# TreeView無限目錄樹實(shí)現(xiàn)方法,實(shí)例分析了TreeView節(jié)點(diǎn)操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
WinForm窗體調(diào)用WCF服務(wù)窗體卡死問題
在Winform窗體中調(diào)用部署在其他服務(wù)器中的WCF服務(wù)時(shí),由于調(diào)用服務(wù)需要一定時(shí)延,因此窗體在這段時(shí)間一直卡住不能進(jìn)行其他操作2012-12-12

