在代码中处理语音命令以执行命令的智能方法 [英] Smart Way to Handle Voice Commands in Code to Action a Command

查看:34
本文介绍了在代码中处理语音命令以执行命令的智能方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与其使用可能会变得非常冗长且非常乏味的 Switch/Case 或 IF 布尔检查,我想知道是否可以找到更好的方法来处理和处理命令.

Rather than using Switch/Case or IF Boolean checks that can get very long and awfully tedious, I wonder if a better way can be sought for handling and processing Commands.

例如:

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

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

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

The if commands go on... Here is a snippet of my Switch Statement:

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 数据库.我根据需要将命令加载到其中.它有一个命令名称列和一个值列.我可以根据需要更改这些以添加更改或删除列.

I have a SQL Database that contains Commands. I Load Commands into it as I need. It has a Command Name Colum and a Value Colum. I can change these to add change or delete columns as needed.

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

Currently, once a command is recognised, I use a combination of IF Statements and a Switch/Case Catch to catch the recognised Command.

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

I have thought about somehow dropping dll's into a folder and some how scanning then on app load. If I add a Command then somehow use the Value Field to action the command in the dll.

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

I realise this is a rather complex situation but I feel a much better solution can be found to make this process much more simple.

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

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

Please ask if you need any more information.

Paqogomez 已经回答了这个问题.请参阅下面的工作示例:

Paqogomez has answered this question. See my working example below:

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,感谢您的分享!这是快速且非常优雅的!.

Beautiful Work Paqogomez and thank you for Sharing! This is fast and very elegant!.

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

In my case, all I need to call the code is:

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

var methods = new Commands();

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

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

which is the Event Handler of the Speech Recognition Engine:

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

推荐答案

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

You are looking for the Strategy pattern as defined here.

这将允许您非常轻松地处理多个 if 语句.

This will allow you to handle multiple if statements very easily.

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

A factory pattern might also suit you. A factory could use reflection to determine which command to create.

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

You could also just dump all your commands into a dictionary.

鉴于最后一点代码示例,您需要一个工厂.我在下面放了一个.

Given the last bit of code example a factory is what you need. I've put one together below.

工厂只是简单地反映 MySpeechMethods 中的所有方法,查找具有 SpeechAttributes 的方法并返回 MethodInfo 以调用.如果您需要方法的返回值,您可以将所有方法设置为返回相同类型(如字符串)或查看泛型,但我将把它留给您.:)

The factory simply reflects on all the methods in MySpeechMethods, looks for ones with SpeechAttributes and sends back the MethodInfo to invoke. If you need return values from your methods you can either set all the methods to return the same type (like string) or look into generics, but I'll leave that to you. :)

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;
        }
    }
}

这篇关于在代码中处理语音命令以执行命令的智能方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆