智能方式处理语音命令的代码操作命令
本文关键字:代码 操作命令 命令 语音 方式 处理 智能 | 更新日期: 2023-09-27 18:30:09
我想知道是否可以找到更好的方法来处理和处理命令,而不是使用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]Paqogomez已经回答了这个问题。请参阅下面的工作示例:
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);
您正在寻找此处定义的Strategy模式。
这将允许您非常容易地处理多个if语句。
工厂模式可能也适合你。工厂可以使用反射来确定要创建哪个命令。
您也可以将所有命令转储到字典中。
编辑:
给定最后一个代码示例,您需要一个工厂。我把一个放在下面。
工厂简单地反映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;
}
}
}