在代码中处理语音命令以执行命令的智能方法

2023-12-13

我想知道是否可以寻求更好的方法来处理和处理命令,而不是使用可能变得非常长且非常乏味的 Switch/Case 或 IF 布尔检查。

E.G:

if(settings.getName == Command)
{
Speak("I am here");
}

if("Get News Feed" == Command)
{
MyRSSFeed RSSNewsFeed = new MyRSSFeed();
RSSNewsFeed.GetFeed();
}

if 命令继续...这是我的 Switch 语句的片段:

switch (Command)
        {
            #region <-- Get Time Command -->

            case "Time Please":
            case "Whats the Time":
            case "What Time is it":
                GetCurrentTime();
                break;

            #endregion <-- Get Time Command -->

            #region <-- Get Date Command -->

            case "Whats the Date":
            case "What Date is it":
            case "Whats the Date Today":
            case "What is the Date Today":
                GetCurrentDate();
                break;

            #endregion <-- Get Date Command -->


            #region <-- Media Player Commands -->

            case "Play Bamboo Forest":

                Data.MusicPlayer.Play(@"\Bamboo Forest Play List.wpl");

                break;

            case "Next Song":

                Data.MusicPlayer.Next();

                break;

            case "Previous Song":

                Data.MusicPlayer.Previous();

                break;

            case "Stop Music":

                Data.MusicPlayer.Stop();

                break;

            case "Pause Music":

                Data.MusicPlayer.Pause();

                break;

            case "Resume Music":

                Data.MusicPlayer.Resume();

                break;


            case "Mute Music":

                Data.MusicPlayer.Mute();

                break;

            case "Volume Up":

                Data.MusicPlayer.VolumeUp();

                break;

            case "Volume Down":

                Data.MusicPlayer.VolumeDown();

                break;

            #endregion <-- Media Player Commands -->

            #region <-- Voice Recognition Control Commands -->

            case "Stop Listening":
                Audio.Listen.NewCommandRecognitionEngine.RecognizeAsyncCancel();
                Audio.Voice.Speak("Ok");
                Audio.Listen.Initialise(main);
                break;

            #endregion <-- Voice Recognition Control Commands -->

            #region <-- Application Commands -->

            case "Quiet":
                Audio.Voice.Stop();
                break;

            case "Download":
                Audio.Voice.Speak("Opening Download Window.");
                main.dlInterface.ShowBitsJobs();
                break;

            case "Settings":
                Audio.Voice.Speak("Opening Settings Window.");
                main.settings.Show();
                break;

            case "Close":
                if (main.dlInterface.Visable == true)
                {
                    main.dlInterface.Hide();
                    Audio.Voice.Speak("Closing Download Window.");
                }
                if (main.settings.Visible == true)
                {
                    main.settings.Hide();
                    Audio.Voice.Speak("Closing Settings Window.");
                }
                break;

            case "Out of the way":
                if (main.WindowState == System.Windows.Forms.FormWindowState.Normal)
                {
                    main.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                    Audio.Voice.Speak("My apologies");
                }
                break;

            case "Where Are You":
                if (main.WindowState == System.Windows.Forms.FormWindowState.Minimized)
                {
                    main.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    Audio.Voice.Speak("Here");
                }
                break;


            default:
                // Do Nothing here...
                break;
        }

我有一个包含命令的 SQL 数据库。我根据需要将命令加载到其中。它有一个命令名称列和一个值列。我可以根据需要更改这些以添加更改或删除列。

目前,一旦识别出命令,我就会使用 IF 语句和 Switch/Case Catch 的组合来捕获识别的命令。

我考虑过以某种方式将 dll 放入文件夹中,以及如何在应用程序加载时进行扫描。如果我添加一个命令,然后以某种方式使用值字段来操作 dll 中的命令。

我意识到这是一个相当复杂的情况,但我觉得可以找到更好的解决方案来使这个过程变得更加简单。

编辑:我已经看过了:http://social.msdn.microsoft.com/Forums/en-US/4f962dc0-aec2-4191-9fe2-e1dfeb1da5dd/voice-command-api

请询问您是否需要更多信息。

[EDIT]帕科戈麦斯回答了这个问题。请参阅下面我的工作示例:

using System;
using System.Linq;
using MyApp.AppCommands;
using System.Reflection;
using System.Collections.Generic;

namespace MyApp
{
class Program
{
static void Main(string[] args)
{
MethodInfo myMethod;

var methods = new Commands();

myMethod = CommandFactory.GetCommandMethods("Time Please");
myMethod.Invoke(methods, null);

myMethod = CommandFactory.GetCommandMethods("Volume Down");
myMethod.Invoke(methods, null);

myMethod = CommandFactory.GetCommandMethods("Volume Up");
myMethod.Invoke(methods, null);

Console.ReadLine();
}
}

public static class CommandFactory
{
private static Dictionary<string, MethodInfo> commandMethods = new Dictionary<string, MethodInfo>();

public static MethodInfo GetCommandMethods(string Command)
{
MethodInfo methodInfo;

var myCommandMethods = new Commands();

if (commandMethods.Count == 0)
{
var methodNames = typeof(Commands).GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);

var speechAttributeMethods = methodNames.Where(y => y.GetCustomAttributes().OfType<CommandAttribute>().Any());

foreach (var speechAttributeMethod in speechAttributeMethods)
{
foreach (var attribute in speechAttributeMethod.GetCustomAttributes(true))
{
commandMethods.Add(((CommandAttribute)attribute).CommandValue, speechAttributeMethod);
}
}
methodInfo = commandMethods[Command];
}
else
{
methodInfo = commandMethods[Command];
}

return methodInfo;
}
}
}

namespace MyApp.AppCommands
{
public class Commands
{
[Command("Time Please")]
[Command("Whats the Time")]
[Command("What Time is it")]
public void GetTime()
{
Console.WriteLine(DateTime.Now.ToLocalTime());
}

[Command("Volume Down")]
public void VolumeDown()
{
Console.WriteLine("Volume Down 1");
}

[Command("Volume Up")]
public void VolumeUp()
{
Console.WriteLine("Volume Up 1");
}
}

[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
public class CommandAttribute : System.Attribute
{
public string CommandValue { get; set; }

public CommandAttribute(string textValue)
{
this.CommandValue = textValue;
}
}
}

漂亮的作品 Paqogomez,感谢您的分享!这很快而且非常优雅!

就我而言,我需要调用的代码是:

private static void CommandRecognized(object sender, SpeechRecognizedEventArgs e)
{
MethodInfo myMethod;

var methods = new Commands();

myMethod = CommandFactory.GetCommandMethods(e.Result.Text);
myMethod.Invoke(methods, null);
}

这是语音识别引擎的事件处理程序:

CommandRecognitionEngine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(CommandRecognized);

您正在寻找定义的策略模式here.

这将使您能够非常轻松地处理多个 if 语句。

工厂模式可能也适合您。工厂可以使用反射来确定要创建哪个命令。

您也可以将所有命令转储到字典中。

EDIT:

鉴于最后一段代码示例,工厂就是您所需要的。我在下面整理了一份。

工厂简单地反映了所有方法MySpeechMethods,寻找具有SpeechAttributes并发回MethodInfo来调用。如果您需要从方法中返回值,您可以将所有方法设置为返回相同类型(如字符串)或查看泛型,但我会将其留给您。 :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MyApp.SpeechMethods;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var methods = new MySpeechMethods();
            MethodInfo myMethod;
            myMethod = SpeechFactory.GetSpeechMethod("Time Please");
            myMethod.Invoke(methods, null);
            myMethod = SpeechFactory.GetSpeechMethod("Volume Down");
            myMethod.Invoke(methods, null);
            myMethod = SpeechFactory.GetSpeechMethod("Volume Up");
            myMethod.Invoke(methods, null);
        }
    }

    public static class SpeechFactory
    {
        private static Dictionary<string, MethodInfo> speechMethods = new Dictionary<string, MethodInfo>();
        public static MethodInfo GetSpeechMethod(string speechText)
        {
            MethodInfo methodInfo;
            var mySpeechMethods = new MySpeechMethods();
            if (speechMethods.Count == 0)
            {
                var methodNames =
                    typeof (MySpeechMethods).GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
                var speechAttributeMethods = methodNames.Where(y => y.GetCustomAttributes().OfType<SpeechAttribute>().Any());
                foreach (var speechAttributeMethod in speechAttributeMethods)
                {
                    foreach (var attribute in speechAttributeMethod.GetCustomAttributes(true))
                    {
                        speechMethods.Add(((SpeechAttribute)attribute).SpeechValue, speechAttributeMethod);
                    }
                }
                methodInfo = speechMethods[speechText];
            }
            else
            {
                methodInfo = speechMethods[speechText];
            }

            return methodInfo;
        }
    }
}

namespace MyApp.SpeechMethods
{
    public class MySpeechMethods
    {
        [Speech("Time Please")]
        [Speech("Whats the Time")]
        [Speech("What Time is it")]
        public void GetTime()
        {
            Console.WriteLine(DateTime.Now.ToLocalTime());
        }

        [Speech("Volume Down")]
        public void VolumeDown()
        {
            Console.WriteLine("Volume Down 1");
        }

        [Speech("Volume Up")]
        public void VolumeUp()
        {
            Console.WriteLine("Volume Up 1");
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
    public class SpeechAttribute : System.Attribute
    {
        public string SpeechValue { get; set; }

        public SpeechAttribute(string textValue)
        {
            this.SpeechValue = textValue;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在代码中处理语音命令以执行命令的智能方法 的相关文章

  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 计算 Richtextbox 中所有单词的最有效方法是什么?

    我正在编写一个文本编辑器 需要提供实时字数统计 现在我正在使用这个扩展方法 public static int WordCount this string s s s TrimEnd if String IsNullOrEmpty s re
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 当我们想要返回对象的引用时,为什么我们在赋值运算符中返回 *this 而通常(而不是 this)?

    我正在学习 C 和指针 我以为我理解了指针 直到我看到这个 一方面 asterix 运算符是解引用的 这意味着它返回值所指向的地址中的值 而与号 运算符则相反 它返回值存储的地址记忆 现在阅读有关赋值重载的内 容 它说 我们返回 this因
  • 为什么极端下派生类(多重虚拟继承)的大小包括超类成员大小的两倍?

    include
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • C# HashSet 只读解决方法

    这是示例代码 static class Store private static List
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List

随机推荐

  • Chrome 调试器 Api 附加扩展错误

    Task 使用调试其他扩展Chrome 调试器 API 预期输出 其他已安装扩展发出的 http 请求日志 Method 在 python 设置标志中使用 selenium 运行 chrome webdriverchromeopts add
  • 如何使用 VBScript 从驱动器号获取硬盘号

    如何使用 VBScript 从驱动器号获取硬盘号 先感谢您 Remou 关于 WMI 的看法是正确的 只是需要让它变得更混乱一点 如果有更简单 更好的方法来执行此操作 一点也不会感到惊讶 但此脚本至少应该为您提供一个良好的起点来完成您需要的
  • 使用安全登录进行 PHP 网站抓取

    我正在尝试减少我的一位经销商的每种产品的库存数量 他们不知道如何导出这些数据 所以我想知道是否有人可以帮助我指明如何使用 PHP 抓取必须登录才能获取数据的网站的正确方向 它不是一个使用 SSL 的安全站点 感谢您的任何提示 克里斯 爱德华
  • C 中是否有 strtoull() 函数的替代方案?

    我需要转换char to unsigned long long int有一个函数叫做strtoull in the C标准库 但需要很多时间 我需要在之间快速转换char to unsigned long long int 如何编写比标准转
  • 日期列中的 Kendo 网格格式时间问题[重复]

    这个问题在这里已经有答案了 我有一个剑道网格 它有一个日期列 我想在那里显示日期和时间 我在列定义中使用以下格式 format 0 dd MMM yyyy hh mm ss tt 在模态中我使用了日期类型Updated Date type
  • UnsupportedAudioFileException 的解决方法?

    我正处于用 Java 编写小型音乐 节奏游戏的早期阶段 通过 Slick 框架 该框架又使用 OpenAL 但这可能与这里无关 游戏需要读取 并播放 多个 WAV 格式的声音文件 但某些文件抛出 javax sound sampled Un
  • 在 cookie 中存储数组

    我需要在 cookie 中存储一些数组数据 我一直在研究最好的方法来做到这一点 很多人似乎说使用serialize是要走的路 但在这个线程中 PHP如何字符串化数组并存储在cookie中 有人建议不要使用它 因为 序列化将调用序列化类的构造
  • 在函数中使用 dplyr group_by

    我试图在本地函数中使用 dplyr 的 group by 例如 testFunction lt function df x df gt group by x gt summarize mean Petal Width mean Petal
  • 使用 Bootstrap Datepicker 时如何获取选定的日期值?

    使用 jquery 和 Bootstrap Datepicker 如何获取我使用 Bootstrap Datepicker 选择的新日期值 仅供参考 我正在使用 Rails 3 和 Coffescript 我使用以下方法设置日期选择器
  • 具有多对多关系的 MVC4 控制器

    我有两个实体 Arena 和 Regulator 它们之间具有多对多的关系 我已经实现了 EF 代码首先接受的解决方案 见下文 我现在一直致力于实现控制器视图 以便当用户创建调节器时 他可以选择一个或多个竞技场 可能使用复选框或多选列表 并
  • 通过 xpath Selenium java 选择具有动态生成的 id 的 WebElements

    我需要在下拉窗口中选择一个元素 每次我在正在测试的网站中打开下拉窗口时 网站都会随机生成该下拉窗口的 ID 下拉窗口的先前实例可见 使用 Firebug 但不可选择 有一个静态路径 但仅当我使用 ChromeDriver 测试它时才有效 而
  • 用于任意对象的 python 哈希函数的替代方案

    在python2 7中 我成功使用hash 将对象放入持久存储在磁盘上的存储桶中 样机代码如下所示 class PersistentDict object def setitem self key value bucket index ha
  • 基本 Docker 容器报告运行级别未知

    当我像这样运行一个基本的 Docker 容器 从 Google Cloud Shell 中 时 docker pull debian docker run i t debian wheezy bin bash 然后输入runlevel在运行
  • 查找给定矩阵的子矩阵

    我正在尝试编写一种算法来在给定的子矩阵中查找子矩阵 为了解决这个问题我编写了以下代码 public class SubMatTry param args public static void main String args TODO Au
  • 添加到 Google 日历呈现链接不显示用户的当地时间

    我可以使用此谷歌日历链接创建一个活动 但我认为 UTC 时间即将到来 比我想要的活动时间提前了 5 30 小时 例子 这个链接将创建一个活动 但显示时间为中午 12 30 至下午 4 点 该活动预计在上午 6 30 至上午 10 点进行 根
  • 是否可以使用单个 SQL 语句将记录从一个表移动到另一个表?

    我需要一个查询将记录从一个表移动到另一个表而不使用多个语句 不可以 您不能在一条 SQL 语句中移动记录 你必须使用一个INSERT随后是一个DELETE陈述 您应该将这些语句包装成交易 以确保复制操作保持原子性 START TRANSAC
  • 使用 oauth2 和 Google API 时无法识别的参数

    我在一些脚本中使用 Google API 服务 但遇到了一些问题 这个错误有点奇怪 但我们开始了 我有一个列出我的 Google 云端硬盘文件的脚本 from apiclient import discovery from httplib2
  • 如何获取成员变量的注解?

    我想知道一个类的一些成员变量的注释 我使用BeanInfo beanInfo Introspector getBeanInfo User class 反思一个类 并使用BeanInfo getPropertyDescriptors 查找特定
  • 如何从一个元组到一个元组引用元组中的元素?

    我有一个 C 11 元组 我想要一个元组std reference wrappers 到元组的相同元素 有没有简单的方法可以做到这一点 映射一个元组很容易一组索引 e g include
  • 在代码中处理语音命令以执行命令的智能方法

    我想知道是否可以寻求更好的方法来处理和处理命令 而不是使用可能变得非常长且非常乏味的 Switch Case 或 IF 布尔检查 E G if settings getName Command Speak I am here if Get