Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

Coding4Fun–Microsoft Speach API 筆記

$
0
0

前篇文章用 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 好威呀!


Viewing all articles
Browse latest Browse all 2311

Trending Articles