首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 語音合成實戰:使用 Microsoft SAPI 實現文字轉語音 (TTS) 與 WAV 檔產生

     編輯:關於C語言

前言:為專案尋找語音引擎

因參加「挑戰杯」專案需整合語音功能,經調研發現微軟 SAPI (Speech API) 是成熟且易用的選擇。本文整理從 MSDN 學習的核心程式碼,示範如何在 C# Windows Forms 專案中實現「即時朗讀」與「匯出 WAV 檔」雙重功能,並支援中英文語音切換。

環境準備與參考加入

SAPI 為 COM 元件,需在專案中加入參考:

  1. 方案總管 → 專案右鍵 → 加入參考 → COM 標籤。
  2. 勾選 Microsoft Speech Object Library (會產生 SpeechLib 互通組件)。
  3. 或使用命令列工具 tlbimp.exe 手動產生 DotNetSpeech.dll。
using DotNetSpeech; // 或 using SpeechLib;

表單設計與核心程式碼

UI 配置

  • GroupBox:包含多行 TextBox (textBox1) 輸入待合成文字。
  • 兩個 RadioButton:radioButtonChina (預設勾選)、radioButtonEnglish 切換語言。
  • Button:buttonSynthes (朗讀)、buttonTTStoWave (存成 WAV)。

核心邏輯:按鈕事件處理

private void buttonSynthes_Click(object sender, System.EventArgs e)
{
    try
    {
        SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync; // 非同步播放
        SpVoice voice = new SpVoiceClass();

        // 依語言選擇語音引擎
        if (radioButtonEnglish.Checked)
            voice.Voice = voice.GetVoices("language=409", "").Item(0); // 英文 (en-US)
        else
            voice.Voice = voice.GetVoices("language=804", "").Item(0); // 中文 (zh-CN)

        voice.Speak(this.textBox1.Text, SpFlags);
    }
    catch (Exception ex)
    {
        MessageBox.Show("發生錯誤!", "SpeechApp", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

private void buttonTTStoWave_Click(object sender, System.EventArgs e)
{
    try
    {
        SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
        SpVoice Voice = new SpVoiceClass();

        SaveFileDialog sfd = new SaveFileDialog();
        sfd.Filter = "所有檔案 (*.*)|*.*|WAV 檔案 (*.wav)|*.wav";
        sfd.Title = "儲存為語音檔";
        sfd.FilterIndex = 2;

        if (sfd.ShowDialog() == DialogResult.OK)
        {
            SpeechStreamFileMode SpFileMode = SpeechStreamFileMode.SSFMCreateForWrite;
            SpFileStream SpFileStream = new SpFileStreamClass();
            SpFileStream.Open(sfd.FileName, SpFileMode, false);

            // 將音訊輸出導向檔案串流
            Voice.AudioOutputStream = SpFileStream;

            // 同樣依語言選擇引擎
            if (radioButtonEnglish.Checked)
                Voice.Voice = Voice.GetVoices("language=409", "").Item(0);
            else
                Voice.Voice = Voice.GetVoices("language=804", "").Item(0);

            Voice.Speak(this.textBox1.Text, SpFlags);
            Voice.WaitUntilDone(Timeout.Infinite); // 等待合成完成
            SpFileStream.Close();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("發生錯誤!", "SpeechApp", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

關鍵技術細節解析

項目說明
SVSFlagsAsync非同步旗標,呼叫 Speak 後立即返回,不阻塞 UI 執行緒。
GetVoices("language=XXXX")依語言代碼 (LCID) 篩選已安裝的語音引擎。409 = 英文(美國),804 = 中文(簡體)。繁體中文通常為 1028 (0x0404),若系統安裝繁中引擎可改用 language=1028。
AudioOutputStream將預設喇叭輸出重導向至 SpFileStream,實現語音存檔。
WaitUntilDone區塊式等待非同步合成完成,確保檔案寫入完整後再關閉串流。

常見問題與避坑指南

  • 找不到語音引擎: 確認控制台 → 語音辨識 → 文字轉語音 索引標籤中已安裝對應語言的語音 (如 Microsoft Lili、Microsoft Huihui 等)。
  • 執行緒模型: SAPI 物件需在 STA 執行緒建立,故 Main() 必須標記 [STAThread]。
  • 部署需求: 目標機器需安裝 Microsoft Speech SDK 5.1 或更新版本,且已註冊對應語言的 TTS 引擎。
  • 授權注意: 微軟內建語音引擎授權僅限 Windows 平台使用,商業軟體分發前請確認授權條款。

擴充應用建議

  1. 語速/音量控制: 透過 voice.Rate (-10~10) 與 voice.Volume (0~100) 調整。
  2. SSML 標記支援: 使用 Speak 多載接受 XML 格式 SSML,可精細控制停頓、音調、重音。
  3. 非同步進度回報: 訂閱 SpeakStarted、SpeakProgress、SpeakCompleted 事件實現進度列與高亮同步。
  4. 跨平台替代: .NET Core / .NET 5+ 專案可改用 System.Speech.Synthesis (僅限 Windows) 或第三方雲端 TTS 服務 (Azure Cognitive Services, Google Cloud TTS)。

結語

透過 Microsoft SAPI,我們以不到 50 行核心程式碼完成了功能完整的中英雙語 TTS 工具。無論是輔助閱讀、無障礙應用,還是自動化語音通知系統,這都是極具性價比的起手式。建議進一步探索 SSML 與事件驅動模型,釋放 SAPI 更強大的表現力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved