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

C# 語音辨識實戰(下):基於 SAPI 5.1 實現中文語音輸入

     編輯:關於C語言

前言

承接上篇語音合成,本文完成 SAPI 5.1 另一大核心能力:語音辨識 (Speech Recognition, SR)。透過 SpSharedRecoContext(共享辨識上下文)與 ISpeechRecoGrammar(口語文法),實現中文口述輸入文字,支援啟動/停止、事件驅動結果回呼、UI 執行緒安全更新。

核心類別設計:SpeechRecognizer


using System;
using System.Windows.Forms;
using SpeechLib;

public class SpeechRecognizer
{
    private static SpeechRecognizer _instance;
    private SpSharedRecoContextClass _recoContext;
    private ISpeechRecoGrammar _grammar;
    private Control _displayControl; // 結果顯示目標控制項

    private SpeechRecognizer() {
        _recoContext = new SpSharedRecoContextClass();
        _grammar = _recoContext.CreateGrammar(1); // 文法 ID

        // 訂閱辨識事件
        _ISpeechRecoContextEvents_RecognitionEventHandler handler = 
            new _ISpeechRecoContextEvents_RecognitionEventHandler(OnRecognition);
        _recoContext.Recognition += handler;
    }

    public static SpeechRecognizer Instance {
        get {
            if (_instance == null) _instance = new SpeechRecognizer();
            return _instance;
        }
    }

    // 開始聽寫模式
    public void StartDictation(Control displayControl) {
        _displayControl = displayControl;
        _grammar.DictationSetState(SpeechRuleState.SGDSActive);
    }

    // 停止辨識
    public void StopDictation() {
        _grammar.DictationSetState(SpeechRuleState.SGDSInactive);
    }

    // 辨識事件回呼(在 SAPI 工作執行緒觸發)
    private void OnRecognition(
        int streamNumber,
        object streamPosition,
        SpeechRecognitionType recognitionType,
        ISpeechRecoResult result)
    {
        string text = result.PhraseInfo.GetText(0, -1, true); // 取得辨識文字

        // 跨執行緒更新 UI:使用 Control.Invoke
        if (_displayControl != null && _displayControl.InvokeRequired) {
            _displayControl.Invoke(new Action(() => {
                _displayControl.Text += text + " ";
            }));
        } else if (_displayControl != null) {
            _displayControl.Text += text + " ";
        }
    }
}

使用範例:WinForms 語音輸入示範


public partial class MainForm : Form {
    private SpeechRecognizer _recognizer;

    public MainForm() {
        InitializeComponent();
        _recognizer = SpeechRecognizer.Instance;
    }

    private void btnStart_Click(object sender, EventArgs e) {
        _recognizer.StartDictation(txtResult); // txtResult 為 TextBox
        btnStart.Enabled = false;
        btnStop.Enabled = true;
    }

    private void btnStop_Click(object sender, EventArgs e) {
        _recognizer.StopDictation();
        btnStart.Enabled = true;
        btnStop.Enabled = false;
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
        _recognizer.StopDictation();
        base.OnFormClosing(e);
    }
}

關鍵技術點深度解析

  1. 共享辨識上下文:SpSharedRecoContextClass 連接系統共享辨識器(任務列語音列),無需獨佔音訊裝置,適合桌面應用
  2. 聽寫文法:DictationSetState(SGDSActive) 載入系統內建大詞彙統計語言模型,支援自由語句辨識;相對的是命令與控制文法(CFG/GRXML),限定詞彙、準確率高
  3. 事件模型:Recognition 事件在 SAPI 內部執行緒觸發 → 必須用 Control.Invoke/BeginInvoke 回 UI 執行緒,否則跨執行緒操作 UI 會拋例外或行為未定義
  4. 結果物件:ISpeechRecoResult 包含 PhraseInfo(辨識片語)、Alternates(備選結果)、Audio(原始音訊)等豐富資訊
  5. 單例模式:共享辨識器系統資源昂貴,全程單一實例

進階:命令與控制文法(提高準確率)

自由聽寫錯誤率較高。若應用場景為固定指令(如「開啟檔案」、「儲存」、「列印」),應使用 XML 文法 (GRXML):


// 定義 commands.grxml


  
    
      開啟檔案
      儲存檔案
      列印文件
      結束程式
    
  


// 載入文法
_grammar.CmdLoadFromFile("commands.grxml", SpeechLoadOption.SLOStatic);
_grammar.CmdSetRuleState("commands", 0, SpeechRuleState.SGDSActive);

此模式辨識準確率大幅提升,適合語音控制類應用。

常見問題排查

現象可能原因對策
無反應/不觸發事件麥克風未設為預設錄音裝置、隱私權限未開啟控制台→聲音→錄音 設定預設;Win10 設定→隱私權→麥克風 允許應用存取
辨識為亂碼/英文語言模型未安裝或非中文環境確認安裝 Speech SDK 5.1 Language Pack (Chinese Simplified);系統地區語言設為中文
CPU 佔用高共享辨識器持續運作不使用時呼叫 StopDictation();或改用 InProcRecognizer (獨佔模式) 按需啟動
Invoke 例外表單關閉後事件仍觸發FormClosing 時 StopDictation() 並取消訂閱事件

架構比較:SAPI 5.1 vs System.Speech vs Azure Speech

特性SAPI 5.1 (COM)System.Speech (Managed)Azure Speech SDK
平台Windows OnlyWindows Only跨平台 (Win/Linux/Mac/iOS/Android)
中文支援需 Language Pack內建 (Win7+)雲端高精度,支援方言/領域適應
部署需安裝 SDK.NET 3.0+ 內建NuGet 套件,需網路/金鑰
離線辨識是是否 (需混合模式)
授權成本免費免費按使用量付費

總結

SAPI 5.1 提供了完整的 COM 級語音辨識能力。本文實現的 SpeechRecognizer 類別展示了核心模式:共享上下文 + 聽寫文法 + 事件回呼 + 跨執行緒 UI 更新。理解 文法類型選擇(聽寫 vs 命令控制)、音訊裝置配置、執行緒邊界處理 是落地關鍵。現代新專案建議優先評估 System.Speech.Recognition (Managed Wrapper) 或 Azure Speech SDK,但 SAPI 5.1 互操作技術在維護舊系統、特定嵌入式 Windows 環境仍具不可替代價值。

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