Coding4Fun–Microsoft Speach API 筆記
8 |
前篇文章用 Balabolka 搞定自製英文單字朗讀 MP3,但老讀者們都猜到接下來會發生什麼事... 是的,C# 整合 SAPI 讓電腦講話的練習來了!
原本以為要裝什麼 SDK 或套件,沒想到 .NET 已內建,專案只需參照 System.Speech 就好。
開始前先看一下你的 Windows 裝了哪些語音以及其支援語系:
static void ListInstalledVoices()
{
var voice = new System.Speech.Synthesis.SpeechSynthesizer();
voice.GetInstalledVoices()
.ToList().ForEach((v) =>
{
Console.WriteLine(
v.VoiceInfo.Name + " " +
v.VoiceInfo.Culture.DisplayName);
});
Console.Read();
}
在我的 Windows 10 繁體中文專業版執行結果如下:
Microsoft Hanhan Desktop 中文 (繁體,台灣)
Microsoft Zira Desktop 英文 (美國)
Microsoft Tracy Desktop 中文 (繁體,香港特別行政區)
Microsoft David Desktop 英文 (美國)
依據文件,Windows 10 2018 4 月更新有增加其他語音選項,國語部分加入了 Zhiwei(志偉?) 跟 Yating (雅婷?)。
來個最基本的應用示範,其中包含前篇文章提到的某段文字用不同語音朗讀。要加入 <voice> 標籤有兩種做法,第一種是自己組 SSML 再呼叫 SpeakSsml(),但得自己處理 XML namespace 比較繁瑣,另一種做法是使用 PromptBuilder,透過 AppendText() 加入純文字,用 AppendSsmlMarkup() 加入包含 <voice> 等標籤的 SSML 片段,最後將 PromptBuilder 當成參數交給 Speak() 執行,比拼湊 XML 省事也易讀一些。
static void SayHi()
{
var voice = new System.Speech.Synthesis.SpeechSynthesizer();
//美語 男聲
voice.SelectVoice("Microsoft David Desktop");
voice.Speak("Hi there, I am darkthread.");
//美語 女聲
voice.SelectVoice("Microsoft Zira Desktop");
voice.Speak("Hi there, I am darkthread.");
//國語
var pb = new PromptBuilder();
pb.StartVoice("Microsoft Hanhan Desktop");
pb.AppendText("大家好,我是黑暗執行緒");
//https://msdn.microsoft.com/zh-tw/library/hh378418(v=office.14).aspx
pb.AppendSsmlMarkup("<voice name=\"Microsoft David Desktop\">darkthread</voice>");
pb.EndVoice();
voice.Speak(pb);
//廣東話
voice.SelectVoice("Microsoft Tracy Desktop");
voice.Speak("大家好,我是黑暗執行緒");
}
PromptBuilder 除了加入 SSML 標籤,還有其他好用的控制選項,例如:
- AppendAudio()
插入外部聲音檔(WMA) - AppendBreak()
插入停頓 - StartParagraph()/EndParagraph()/StartSentence()/EndSentence()
形成段落跟句子,模擬自然說話的停頓效果,使語音更逼真 - StartVoice()/EndVoice()
指定語音名稱,或指定語系、性別、年齡,由 SAPI 挑選適用的語音
除了前面介紹過的 <voice>,SSML 還有一些有用標籤,可做到精細調控:
(參考:Speech Synthesis Markup Language Reference)
- emphasis
強調,加重語氣 - p、s
標註段落跟句子,讓說話效果更自然逼真 - phoneme
可使用特殊音標指定特定字語的發音,例如指定 Zhou 要唸成「趙」
His name is Mike <phoneme alphabet=""x-microsoft-ups"" ph=""JH AU"">Zhou</phoneme>
參考:發音標示符號表 Phonetic Alphabet Reference - prosody
指定範圍內文字的音調(pitch)、速度(rate)、音量(volume)
Your order for <prosody pitch=""+1st"" rate=""-10%"" volume=""50""> eight books </prosody> - voice
指定範圍內文字使用不同語音
想將語音輸出轉成 WAV 檔也很簡單,在 voice.Speak() 之前先加上 voice.SetOutputToWaveFile("x:\\filename.wav"),一行搞定! 如果要轉成 MP3,則需要整合第三方程式庫或直接用 lame.exe 將 .wav 檔轉 .mp3,lame.exe x:\filename.mav x:\filename.mp3,一樣一行搞定最省事。
又到了久違的呼口號時間:
SAPI 真酷! .NET 好威呀!
Inspired by Balabolka, I tried to write several lines of code to call SAPI to create my custom English vocabularies learning MP3.
Comments
# by not
您好,我想要把產生的語音檔放在iis上,讓使用者下載或是播放,不過把您的範例code放在後端程式呼叫時總是會出現 "非同步作業目前無法開始。" 的錯誤訊息 https://i.imgur.com/TitLzay.png 我想如果要把檔案存成wav後才要顯示網頁,應該是同步程式比較符合我的需求才對,可是連第一步GetInstalledVoices想看裝了哪些語音都過不去... 可以問問要如何在網頁的環境執行嗎?
# by Jeffrey
to not, 可參考Stackoverflow的這則範例,https://stackoverflow.com/a/47300962/288936
# by 阿強
網頁版這個會不會比較方便,我是沒用過。 https://responsivevoice.org/
# by Jeffrey
to 阿強,挺方便的。經實測「 948794 狂」,Chinese Female 語音的效果跟卡提諾狂新聞旁白一木一樣啊 XD 感謝分享
# by Brad
請問有甚麼辦法可以選到Yating 和Zhiwei呢? 因為我已經安裝這兩個聲音,Edge和朗讀程式都可以使用 但是GetInstalledVoices沒有出現, SelectVoice也會失敗
# by Jeffrey
to Brad, Edge跟朗讀程式可用但.NET程式找不到,會跟x64/x86有關嗎? 切換.NET平台目標試看看是否結果不同。
# by Oaww
我分享一下這幾天的心得 1.在Server 找不到語音,一般建議都改用Mircosoft.speech (其實我也不知道為什麼Orz) 2.在發行到Server 的時候IIS的application pool的辨識要改為localService,IIS才有權利執行 3.改成Microsoft.speech的時候有幾個東西要灌,請參考下面網址 https://blog.patw.me/archives/619/c-net-use-text-to-speech-in-microsoft-speech-sdk-11lai-function/ 4.在執行的時候有發現缺DLL,請參考下面網址 https://stackoverflow.com/questions/45101353/microsoft-speech-synthesis-chinese-speak-error-zh-cn-huihui 這幾個步驟讓我可以解決我的問題,希望也可以解決你的問題: D
# by 阿詹
你好,我仿照你的code執行,但只要放進voice.Speak(pb)這一句,語音會出來,但網頁就一直轉。我debug 後端程式,他的確都有跑完,但畫面就出不來,請問可能是什麼原因嗎?