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

C# 整合 Microsoft TTS (SAPI 5.1) 實現中英文語音合成

     編輯:關於C#

前言

.NET Framework 早期版本內建 System.Speech 僅支援英文。若需中文語音合成,需安裝 Microsoft Speech SDK 5.1 及中文語言包 (Tracy/Simplified Chinese),並透過 COM Interop 呼叫 SAPI 物件模型。本文示範完整封裝流程:tlbimp 產生互通組件、單例語音類別、中英文自動切換邏輯、音量/語速控制。

環境準備

  1. 下載安裝 Microsoft Speech SDK 5.1 (sdk51.exe)
  2. 下載安裝 Speech SDK 5.1 Language Pack,選擇 Chinese (Traditional/Simplified)
  3. 確認 C:\Windows\Speech\ 存在 vtxtauto.tlb (SAPI 類型庫)

產生互通組件


# Visual Studio 開發人員命令提示字元
tlbimp.exe "C:\Windows\Speech\vtxtauto.tlb" /namespace:MSTTS /out:MSTTS.dll

產生 MSTTS.dll,加入專案參考即可使用 MSTTS.VTxtAuto 類別。

語音合成封裝類別


using System;
using MSTTS; // 互通組件命名空間

namespace Bedlang
{
    /// 
    /// SAPI 5.1 語音合成包裝,支援中英文混合自動切換語音引擎
    /// 
    public sealed class Speech : IDisposable
    {
        private static readonly Lazy _instance = new(() => new Speech());
        private readonly VTxtAuto _voice;
        private bool _disposed;

        private Speech()
        {
            _voice = new VTxtAuto();
            _voice.Register("", ""); // 註冊 COM 元件 (若需授權碼請填入)
        }

        public static Speech Instance => _instance.Value;

        /// 設定中文語音引擎 (需安裝中文語言包)
        private void SetChineseVoice()
        {
            // GetVoices 索引 0 通常為系統預設中文語音
            _voice.Voice = _voice.GetVoices("", "").Item(0);
        }

        /// 設定英文語音引擎
        private void SetEnglishVoice()
        {
            // 索引 1 通常為英文語音 (Microsoft Sam/Mike/Mary)
            _voice.Voice = _voice.GetVoices("", "").Item(1);
        }

        /// 單一語言朗讀
        private void SpeakInternal(string text)
        {
            try
            {
                // SVSFlagsAsync = 1: 非同步朗讀
                _voice.Speak(text, SpeechVoiceSpeakFlags.SVSFlagsAsync);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"語音合成失敗: {ex.Message}", ex);
            }
        }

        /// 智慧中英文混合朗讀
        public void AnalyseSpeak(string text)
        {
            if (string.IsNullOrEmpty(text)) return;

            int chineseStart = 0, englishStart = 0;
            bool isChinese = true; // 預設第一段為中文

            for (int i = 0; i < text.Length; i++)
            {
                char c = text[i];
                bool charIsEnglish = c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';

                if (isChinese)
                {
                    if (charIsEnglish)
                    {
                        // 中文段結束,朗讀中文段
                        string segment = text.Substring(chineseStart, i - chineseStart);
                        if (!string.IsNullOrWhiteSpace(segment))
                        {
                            SetChineseVoice();
                            SpeakInternal(segment);
                        }
                        englishStart = i;
                        isChinese = false;
                    }
                }
                else // 目前為英文段
                {
                    if (!charIsEnglish)
                    {
                        // 英文段結束,朗讀英文段
                        string segment = text.Substring(englishStart, i - englishStart);
                        if (!string.IsNullOrWhiteSpace(segment))
                        {
                            SetEnglishVoice();
                            SpeakInternal(segment);
                        }
                        chineseStart = i;
                        isChinese = true;
                    }
                }
            }

            // 處理最後一段
            if (isChinese)
            {
                string segment = text.Substring(chineseStart);
                if (!string.IsNullOrWhiteSpace(segment))
                {
                    SetChineseVoice();
                    SpeakInternal(segment);
                }
            }
            else
            {
                string segment = text.Substring(englishStart);
                if (!string.IsNullOrWhiteSpace(segment))
                {
                    SetEnglishVoice();
                    SpeakInternal(segment);
                }
            }
        }

        /// 音量 (0-100)
        public int Volume
        {
            get => _voice.Volume;
            set => _voice.Volume = Math.Clamp(value, 0, 100);
        }

        /// 語速 (-10 到 10)
        public int Rate
        {
            get => _voice.Rate;
            set => _voice.Rate = Math.Clamp(value, -10, 10);
        }

        /// 立即停止朗讀
        public void Stop()
        {
            // SVSFPurgeBeforeSpeak = 1: 清除隊列並停止
            _voice.Speak("", SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
        }

        /// 暫停朗讀
        public void Pause() => _voice.Pause();

        /// 繼續朗讀
        public void Resume() => _voice.Resume();

        public void Dispose()
        {
            if (!_disposed)
            {
                Stop();
                _disposed = true;
            }
        }
    }
}

WinForms 示範程式


using System;
using System.Windows.Forms;
using Bedlang;

public class TtsDemoForm : Form
{
    private TextBox _txtInput;
    private Button _btnSpeak, _btnStop, _btnPause, _btnResume;
    private TrackBar _trkVolume, _trkRate;

    public TtsDemoForm()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
        _txtInput = new TextBox 
        { 
            Location = new Point(10, 10), 
            Size = new Size(400, 100), 
            Multiline = true, 
            ScrollBars = ScrollBars.Vertical,
            Text = "你好 Hello 世界 World!歡迎使用 C# 語音合成。"
        };

        _btnSpeak = new Button { Text = "朗讀", Location = new Point(10, 120), Width = 80 };
        _btnStop = new Button { Text = "停止", Location = new Point(100, 120), Width = 80 };
        _btnPause = new Button { Text = "暫停", Location = new Point(190, 120), Width = 80 };
        _btnResume = new Button { Text = "繼續", Location = new Point(280, 120), Width = 80 };

        _trkVolume = new TrackBar { Location = new Point(10, 160), Width = 200, Minimum = 0, Maximum = 100, Value = 80, TickFrequency = 10 };
        _trkRate = new TrackBar { Location = new Point(10, 200), Width = 200, Minimum = -10, Maximum = 10, Value = 0, TickFrequency = 2 };

        _btnSpeak.Click += (s, e) => Speech.Instance.AnalyseSpeak(_txtInput.Text);
        _btnStop.Click += (s, e) => Speech.Instance.Stop();
        _btnPause.Click += (s, e) => Speech.Instance.Pause();
        _btnResume.Click += (s, e) => Speech.Instance.Resume();
        _trkVolume.ValueChanged += (s, e) => Speech.Instance.Volume = _trkVolume.Value;
        _trkRate.ValueChanged += (s, e) => Speech.Instance.Rate = _trkRate.Value;

        this.Controls.AddRange(new Control[] 
        { 
            _txtInput, _btnSpeak, _btnStop, _btnPause, _btnResume, 
            new Label { Text = "音量", Location = new Point(220, 160), AutoSize = true }, _trkVolume,
            new Label { Text = "語速", Location = new Point(220, 200), AutoSize = true }, _trkRate
        });

        this.Text = "SAPI 5.1 中英文語音合成示範";
        this.ClientSize = new Size(450, 250);
        this.FormClosed += (s, e) => Speech.Instance.Dispose();
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TtsDemoForm());
    }
}

編譯與執行


# 命令列編譯
csc /target:library /out:Bedlang.dll Speech.cs /r:MSTTS.dll
csc /out:TtsDemo.exe TtsDemoForm.cs /r:Bedlang.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll

或直接在 Visual Studio 建立專案,加入 MSTTS.dll 參考即可。

關鍵技術細節

1. 中英文切換邏輯

簡易 ASCII 範圍判斷 (A-Z, a-z) 作為英文識別,其餘視為中文。實際專案建議使用 CharUnicodeInfo.GetUnicodeCategory 精確判斷 UnicodeCategory.OtherLetter (含中日韓統一表意文字)。

2. 非同步朗讀

SpeechVoiceSpeakFlags.SVSFlagsAsync (值 1) 讓 Speak 立即返回,不阻塞 UI 執行緒。停止時使用 SVSFPurgeBeforeSpeak (值 1) 清除待朗讀隊列。

3. 單例模式

SAPI 語音引擎初始化成本高,採用 Lazy<T> 確保執行緒安全單例,應用程式生命週期內只建立一次。

現代替代方案比較

方案優點缺點適用場景
SAPI 5.1 (本文)離線、免費、Windows 內建語音較機械、需安裝 SDK、僅限 Windows舊系統維護、離線嵌入式
System.Speech.NET 內建、API 現代中文需額外安裝語言包、語音品質同 SAPI.NET Framework/Core 桌面應用
Windows.Media.SpeechSynthesis現代語音、支援神經網路、SSML 完整需 UWP/WinUI 3/Windows App SDK現代 Windows 應用開發
Azure Speech SDK最佳語音品質、多語言混合、自訂語音需網路、依用量付費企業級、雲端、跨平台

總結

本文提供完整的 SAPI 5.1 中文語音合成 C# 封裝:tlbimp 互通組件、單例管理、中英文自動切換、音量語速控制、暫停/繼續/停止。雖技術屬前世代,但在無法使用現代語音平台的舊系統維護、離線環境部署中仍具實用價值。新專案強烈建議遷移至 Windows.Media.SpeechSynthesis 或 Azure Speech SDK。

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