You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET控制台应用实现语音识别的可行性及问题咨询

VB.NET 控制台应用实现语音识别完全可行!

首先明确一点:VB.NET是面向对象语言,控制台环境只是没有可视化界面,但事件机制依然可以正常使用——你的问题不是语言特性的限制,而是代码实现上的错误。下面我会分别修正你WinForm和控制台代码里的问题,并给出可运行的版本。

一、WinForm代码的问题与修正

你的WinForm代码里存在三个关键错误:

  1. 同时加载外部XML语法文件又手动构建规则,导致语法冲突;
  2. colourr变量未初始化就调用Add方法,会引发空引用异常;
  3. setcolo方法里创建的SpeechSynthesizer没有实际使用,属于冗余代码。

修正后的WinForm代码(手动构建规则版本)

Imports System.Speech
Imports System.Speech.Recognition
Imports System.Speech.Synthesis

Public Class Form1
    Dim WithEvents recog As New SpeechRecognitionEngine

    Private Sub setcolo(ByVal colour As System.Drawing.Color)
        Me.BackColor = colour
        ' 可选:添加语音反馈
        Using synth As New SpeechSynthesizer
            synth.Speak($"Changed background to {colour.Name}")
        End Using
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        recog.SetInputToDefaultAudioDevice()

        ' 手动构建语法规则,无需依赖外部XML
        Dim colourlist As New SrgsGrammar.SrgsOneOf("red", "yellow", "indigo", "aqua", "green", "blue")
        Dim colourr As New SrgsGrammar.SrgsRule("ColourRule") ' 必须初始化规则实例
        colourr.Add(colourlist)
        
        Dim gram As New SrgsGrammar.SrgsDocument()
        gram.Rules.Add(colourr)
        gram.Root = colourr

        recog.LoadGrammar(New Grammar(gram))
        recog.RecognizeAsync(RecognizeMode.Multiple) ' 指定持续识别模式
    End Sub

    Private Sub recog_RecognizeCompleted(sender As Object, e As RecognizeCompletedEventArgs) Handles recog.RecognizeCompleted
        ' 识别中断时自动重启(无错误情况下)
        If e.Error Is Nothing Then
            recog.RecognizeAsync(RecognizeMode.Multiple)
        End If
    End Sub

    Private Sub recog_SpeechRecognized(sender As Object, e As SpeechRecognizedEventArgs) Handles recog.SpeechRecognized
        ' 增加置信度过滤,减少误识别
        If e.Result.Confidence < 0.7 Then Return
        
        Select Case e.Result.Text.ToLower()
            Case "red" : setcolo(Color.Red)
            Case "yellow" : setcolo(Color.Yellow)
            Case "aqua" : setcolo(Color.Aqua)
            Case "green" : setcolo(Color.Green)
            Case "indigo" : setcolo(Color.Indigo)
            Case "blue" : setcolo(Color.Blue)
        End Select
    End Sub
End Class

若使用外部XML语法文件的版本

确保你的XML符合SRGS规范,示例如下:

<?xml version="1.0" encoding="utf-8"?>
<grammar version="1.0" xml:lang="en-US" root="ColourRule" xmlns="http://www.w3.org/2001/06/grammar">
  <rule id="ColourRule">
    <one-of>
      <item>red</item>
      <item>yellow</item>
      <item>indigo</item>
      <item>aqua</item>
      <item>green</item>
      <item>blue</item>
    </one-of>
  </rule>
</grammar>

然后修改Form_Load方法,直接加载XML即可:

Dim gram As New SrgsGrammar.SrgsDocument("D:\Voiceregogform\Voiceregogform\bin\Debug\ColourGrammar.xml")
recog.LoadGrammar(New Grammar(gram))

二、控制台应用的正确实现

你的控制台代码主要问题是事件绑定错误、Main方法参数错误,以及死循环占用CPU。下面是修正后的可运行版本:

Imports System
Imports System.Speech.Recognition
Imports System.Speech.Synthesis
Imports System.Globalization
Imports System.Threading

Module Module1
    Dim ss As New SpeechSynthesizer
    Dim sre As SpeechRecognitionEngine
    Dim done As Boolean = False
    Dim speechOn As Boolean = True

    Sub Main(args As String()) ' 修正参数类型为String()
        Try
            ss.SetOutputToDefaultAudioDevice()
            Console.WriteLine(vbCrLf & "(Speaking: I am awake)")
            ss.Speak("I am awake")

            Dim ci = New CultureInfo("en-us")
            sre = New SpeechRecognitionEngine(ci)
            sre.SetInputToDefaultAudioDevice()

            ' 正确绑定事件处理程序(VB.NET专属语法)
            AddHandler sre.SpeechRecognized, AddressOf sre_SpeechRecognized
            AddHandler sre.RecognizeCompleted, AddressOf sre_RecognizeCompleted

            ' 构建启停命令语法
            Dim ch_StartStopCommands As New Choices({"speech on", "speech off", "klatu barada nikto"})
            Dim gb_StartStop As New GrammarBuilder(ch_StartStopCommands)
            Dim g_StartStop As New Grammar(gb_StartStop)

            ' 构建加法计算语法
            Dim ch_Numbers As New Choices({"1", "2", "3", "4"})
            Dim gb_WhatIsXplusY As New GrammarBuilder()
            gb_WhatIsXplusY.Append("What is")
            gb_WhatIsXplusY.Append(ch_Numbers)
            gb_WhatIsXplusY.Append("plus")
            gb_WhatIsXplusY.Append(ch_Numbers)
            Dim g_WhatIsXplusY As New Grammar(gb_WhatIsXplusY)

            sre.LoadGrammar(g_StartStop)
            sre.LoadGrammar(g_WhatIsXplusY)
            sre.RecognizeAsync(RecognizeMode.Multiple)

            ' 替换死循环,降低CPU占用
            While Not done
                Thread.Sleep(100) ' 让线程短暂休息
            End While

            Console.WriteLine(vbCrLf & "Hit <enter> to close shell" & vbCrLf)
            Console.ReadLine()
        Catch ex As Exception
            Console.WriteLine($"Error: {ex.Message}")
            Console.ReadLine()
        End Try
    End Sub

    ' 事件处理程序改为Sub(无需返回值)
    Private Sub sre_SpeechRecognized(sender As Object, e As SpeechRecognizedEventArgs)
        Dim txt As String = e.Result.Text
        Dim confidence As Double = e.Result.Confidence
        Console.WriteLine(vbCrLf & $"Recognized: {txt} (Confidence: {confidence:P})")

        If confidence < 0.6 Then Return

        Select Case txt.ToLower()
            Case "speech on"
                Console.WriteLine("Speech is now ON")
                speechOn = True
            Case "speech off"
                Console.WriteLine("Speech is now OFF")
                speechOn = False
            Case "klatu barada nikto"
                sre.RecognizeAsyncCancel()
                done = True
                Console.WriteLine("(Speaking: Farewell)")
                ss.Speak("Farewell")
        End Select

        If Not speechOn Then Return

        ' 安全处理加法计算逻辑
        If txt.StartsWith("What is", StringComparison.OrdinalIgnoreCase) AndAlso txt.Contains("plus") Then
            Dim words() As String = txt.Split({" "}, StringSplitOptions.RemoveEmptyEntries)
            If words.Length >= 5 Then
                If Integer.TryParse(words(2), Dim num1) AndAlso Integer.TryParse(words(4), Dim num2) Then
                    Dim sum As Integer = num1 + num2
                    Dim response As String = $"{num1} plus {num2} equals {sum}"
                    Console.WriteLine($"(Speaking: {response})")
                    ss.SpeakAsync(response)
                End If
            End If
        End If
    End Sub

    Private Sub sre_RecognizeCompleted(sender As Object, e As RecognizeCompletedEventArgs)
        ' 识别意外中断时自动重启(除非程序已标记结束)
        If Not done AndAlso e.Error Is Nothing Then
            sre.RecognizeAsync(RecognizeMode.Multiple)
        End If
    End Sub
End Module

控制台代码的关键修正点:

  1. Main方法参数改为args As String()(符合VB.NET控制台程序标准签名);
  2. 使用AddHandler正确绑定事件处理程序,替代错误的C#风格写法;
  3. 将sre_SpeechRecognized从Function改为Sub(事件处理程序无需返回值);
  4. 替换死循环为带Thread.Sleep的循环,避免CPU占用过高;
  5. 增加Integer.TryParse安全转换,避免字符串转数字的异常;
  6. 使用忽略大小写的字符串比较,提升识别鲁棒性。

总结

VB.NET控制台应用完全可以实现语音识别功能——它是面向对象语言,事件机制在控制台环境中依然有效,只要正确绑定事件处理程序。你的核心问题是代码实现中的语法错误和逻辑问题,而非语言特性的限制。

内容的提问来源于stack exchange,提问作者shellgon26

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:23:09