编写您自己的语音识别应用程序






4.72/5 (11投票s)
编写您自己的语音识别软件
编写您自己的语音识别应用程序
作者:Matthew Mansfield
版权所有 © 2017
创建日期:2013年6月14日
我们都看过《钢铁侠》,无疑都曾想过如何拥有自己的贾维斯,对吧?嗯,如今的操作系统包含了如此多的实用功能、文件和智能代码,可以作为您构建自己的贾维斯的素材;我们将探讨如何制作自己的贾维斯。在本教程中,我将向您展示如何在您的家中或办公室拥有一个语音识别软件程序。
在我们深入探讨之前,我想让您了解几件事。我们要编写的这个程序具有我需要填补的非常具体的功能,而这些功能是我在任何语音识别软件中都找不到的。该软件的一些具体功能包括:
运行可执行程序文件和脚本
提供语音反馈,告知任务是否已完成
监听语音,而不是等待整个段落说完
如果这些功能正是您所感兴趣的,那么请继续阅读,因为本教程就是为您准备的。
本手册假定您具备 C# 语言和 Microsoft Access 的基本到中级实践经验。在本手册中,我将尽力涵盖过程中所需的每一步,但如果遗漏了一两个步骤,我希望您能够自行填补这些空白。祝您在创建个性化语音识别程序的旅程中一切顺利!
目录
第一部分 - Wilson 的起源
- 需求
- 名称
- 用途
第二部分 – 开始您的项目
- 系统要求
- 新项目
- 添加窗体
- 导入引用
- 创建 Access 数据库
第三部分 – 连接各个部分
- 将数据库连接到您的窗体
- 创建数据网格
- 创建文本框和按钮
第四部分 – 完善代码
- Form1 的代码
- Form4 的代码
第五部分 – 附加功能和特性
- 更多想法
- 批处理文件
- VBScript 脚本
- 自动化家电
- 项目下载
- 结论
第一部分 – Wilson 的起源
本部分目标
在本部分中,我们将介绍
- 需求
- 名称
- 用途
需求
2008 年中期,我正在尝试用备件组装一个机械臂。有时这个过程相当费力,我常常希望有一个助手。很多时候,我正在焊接电路板或将一根线从一个地方连接到另一个地方,就需要运行我的代码。运行代码会导致电流流经所有组件,如果布线错误,可能会烧毁伺服电机,甚至整个微控制器。随着我对助手的需求持续存在,我开始好奇如何才能制造一个自动化助手。这种好奇心驱使我去寻找市场上已有的各种语音识别 (VR) 软件解决方案。经过大量的研究、下载和软件试用,我意识到没有任何程序能提供我所寻求的功能。为了保持高效的工作流程,我需要的功能是能够根据语音请求运行应用程序、获得语音确认该应用程序已运行,并在必要时接受单个词语的命令。
名称
最初,当我第一次在办公室实施该应用程序时,我正在进行语音编码器训练阶段,这时我常常会发现我的妻子站在那里。她会问我一些问题,比如:“你难道不知道它不是真的,对吧?”我当然知道它只是个电脑,但用自然的语气说话是它理解您语音的最佳方式。随着时间的推移,她来我办公室的次数越来越多,关于我和电脑说话的笑话也越来越多。很多时候,当我沉迷于一个项目时,我会留长胡子,忘记吃饭和睡觉。有一天,我妻子进来告诉我,我看起来像汤姆·汉克斯在《荒岛余生》里的样子,而我的电脑就像我的威尔逊。从那时起,“威尔逊”这个名字就固定下来了,我的 VR 程序也被命名为 Wilson。在过程的不同阶段,应用程序的声音已经改变了好几次,但通常应用程序的声音是英式男性,这为 Wilson 增添了角色。当然,您可以随意命名您的应用程序,但由于我太习惯于称这个软件解决方案为 Wilson,请不要因为我简单地称它为 Wilson 而感到困惑。
用途
一旦您的语音识别系统启动并运行,您很快就会意识到您可以将它连接到多少东西上。创建 Wilson 的最初目的是在我进行机器人研究时通过调试器运行一些算法。从那时起,Wilson 取得了长足的进步。现在,Wilson 控制了我所有的媒体,并且还与我的云服务器相连。我还使用 Wilson 自动化了办公室里的许多电器设备,最近的愿望是将 VoIP(网络语音电话)与 Wilson 连接起来。
第二部分 – 开始您的项目
本部分目标
在本部分中,我们将介绍
- 系统要求
- 新项目
- 添加窗体
- 导入引用
- 创建 Access 数据库
系统要求
根据我的经验,当满足某些条件时,该程序运行效果最佳。这些条件包括必须使用 Microsoft Windows Experience (XP) 或 Microsoft Server 2008 R2。此外,我注意到,为了获得最佳的 DLL 文件,您必须安装几个包含所需 DLL 文件的应用程序。这是一个较旧的程序,但如果您安装了 Microsoft Office 2003,它包含 Microsoft Speech 模块,该模块将插入到您的控制面板中。安装 MS Office 2003 后,您将能够打开控制面板,选择“语音”(或“文本到语音”,取决于您使用的操作系统)并调整您想要的语音设置。接下来,您需要安装 Dragon Naturally Speaking Premium 11.0,其中包含您运行程序所需的其余 DLL 文件。对于此项目,建议您至少安装 .Net 4 框架。
侧边提示:我知道您可能在想,“我为什么要编写自己的程序,还需要安装所有这些其他软件程序,其中一个还是 VR 程序?”好问题,我喜欢您的想法。我做了大量的 VR 研究,并在我的探索过程中尝试了许多软件解决方案。我的个人目标之一是创建一个可以执行各种任务并在我完成任务后提供语音反馈的程序。Dragon 不具备此功能。Dragon 的某些应用程序允许您通过命令执行应用程序,但使用的语音编码器工作方式很奇怪。Dragon 不会立即执行您说的话,而是长时间监听,以“查看”您是否说完。这是因为 Dragon 监听的是语音段落,这种等待会导致您的程序滞后或响应非常缓慢。我从未能够让 Dragon 快速监听并执行我的命令,这造成了很多沮丧。最后,我找到了 Tazti,这是一个很棒的程序,但目前只允许 75 个自定义命令。这会造成一个很大的问题,因为您可以以多种不同的方式提出同一个请求,例如
“电脑,打开我的文档”
“电脑,请打开我的文档”
“请打开我的文档”
“打开我的文档”
“请打开我的文档”
“我的文档”
“我的文档,请”
不用说,75 个命令很快就会用完。我们将要编写的这个应用程序将允许您拥有高达 1600 万个命令,这应该足以满足增长的需求。
为了增加一些变化,您可以购买一些高级语音包,为您的应用程序增添更多个性,并提升与计算机交流的体验。Cepstral 以可承受的价格制作了一些非常好的语音。此外,您还可以通过 NeoSpeech(我最喜欢的是 Julie)找到一些不错的语音。
新项目
我最喜欢的编程套件是 Microsoft 的 Visual Studio 2010 Ultimate。在本教程中,我将使用它作为我的首选应用程序。首先,我们通过从“文件”下拉菜单中选择并单击“新建项目”来启动一个新项目。
接下来,我们将选择要编程的语言。出于我们的目的,我们将使用 C#。然后,我们将根据您的喜好命名项目。
点击“确定”后,您将看到准备就绪的新窗体。
添加窗体
所以,您应该看到您的窗体,其默认名称为 Form1。您可以随意命名您的项目,但我将保持名称不变。接下来,打开您的“解决方案资源管理器”,右键单击您的项目,选择“添加” > “新项”,然后选择“Windows 窗体”。同样,您可以随意命名此窗体,但我将称我的为 Form4(默认应为 Form2.cs)。
导入引用
在此,我将为您提供一个需要添加到项目中的导入列表。要导入引用,您必须打开“解决方案资源管理器”,右键单击“引用”,然后选择“添加引用…” > “COM”选项卡,选择您想包含在项目中的引用,然后单击“确定”。在项目完成之前,您需要的引用有:
- ADODB
- DAO
- Interop.SpeechLib
- LumiSoft.Net
- Microsoft.CSharp
- Microsoft.Office.Core
- Microsoft.Office.Interop.Access
- Microsoft.VisualBasic
- Microsoft.VisualBasic.PowerPacks.Vs
- MouseKeyboardLibrary
- 系统
- System.Core
- System.Data
- System.Data.DataSetExtensions
- System.Deployment
- System.Design
- System.Drawing
- System.Speech
- System.Windows.Forms
- System.Xml
- System.Xml.Linq
- Vallelunga.HomeAutomation
- VBIDE
上面列表中标有红色的引用是您首次打开新项目时不存在的。许多对直接链接库 (DLL) 文件的引用将在您编写应用程序的不同阶段添加。自动添加引用是 Visual Studio 的一项功能。但是,如果由于某种原因您缺少或找不到一个在您继续创建程序时通常不会自动添加的 DLL,您可以在此处下载额外的 DLL HERE,并在完成之前确保它们都已到位。该链接指向一个 zip 文件,我已为您提供,方便您下载和按需使用。
创建 Access 数据库
这里是拥有 MS Access 基本到中级经验派上用场的地方,因为我们不会在这里详细介绍整个过程。我通常使用 MS Access 2007,所以我的说明将针对该版本。首先,选择左上角的 Windows 图标,然后单击“新建”。随便您如何命名数据库;在本教程中,我将把我的命名为 VR.accdb。创建一个项目可用的数据库。我将其命名为 CustomCommands,并包含了以下字段:
- ID
- CommonField
- 命令
- 结果
保存该数据库,以便在下一步中使用。
第三部分 – 连接各个部分
本部分目标
在本部分中,我们将介绍
- 将数据库连接到您的窗体
- 创建数据网格
- 创建文本框和按钮
将数据库连接到您的窗体
得益于 MS Visual Studio,您可以拖放许多对象,然后它会自动添加许多连接字符串。让我们现在开始将数据库连接到您的窗体。首先,转到“数据源”,然后选择“添加新数据源…”这将打开一个“数据源配置向导”,它将引导您完成添加数据库连接的步骤。
在将程序连接到您创建的 MS Access 数据库后,我们将把该数据库添加到我们的程序窗体中。您会看到您的“数据集”现在已在“数据源”下。
在这里,您可以单击并拖动给定的字段,例如“Command”或“Result”,将它们拖到您的窗体上。只需确保字段设置为“TextBox”,您就应该会看到一个类似于此的窗体:
“Common Field”字段是计算机对您说的话,“Command”字段是您对计算机说的话,而“Result”字段是要执行的程序。为了帮助我 mentally 区分它们,我将重命名我的标签以实现这一点。我们刚刚演示了如何将数据库连接到一个窗体。您可以按照本节中列出的相应步骤,将此数据库连接到您的第二个窗体。
创建数据网格
在我们的主窗体上,我们不需要数据网格视图,但在第二个窗体上我们需要。网格视图并非完全必需,但它有助于您在管理命令时保持条理。在“数据源”资源管理器下,选择“CustomCommands”,然后从下拉菜单中选择“DataGridView”。然后,只需用鼠标拖动“CustomCommands”到您的窗体上。从那里,您可以随意排列您的数据网格视图。
创建文本框和按钮
现在,我们可以创建所有我们需要的按钮和文本框。为了简单起见,我们将分步进行。
对于 Form1,请执行以下操作:
- 第 1 步 - 重命名以下标签
- “Command”字段将变为“您的语音命令:”
- “Result”字段将变为“启动程序:”
- “Common Field”字段将变为“PC 说的话”
- 第 2 步 - 添加 button1 并将文本更改为“关闭此窗口”
- 第 3 步 - 添加 button2 并将文本更改为“打开搜索框”
- 第 4 步 - 添加 groupBox1 并移除文本
- 第 5 步 - 在 groupBox1 内添加 radioButton1 并将文本更改为“网站”
- 第 6 步 - 在 groupBox1 内添加 radioButton2 并将文本更改为“程序”
- 第 7 步 - 添加 button3 并将其名称更改为 btnSave,并将文本更改为“保存”
- 第 8 步 - 添加 button4 并将其名称更改为 btnOpen,并将文本更改为“打开”
- 第 9 步 - 添加 button5 并将其名称更改为 btnToListbox,并将文本更改为“添加到列表框”
对于 Form4,请执行以下操作:
- 第 1 步 - 添加 button1 并将其命名为 button4
- 第 2 步 - 添加文本框并称其为 textBox1
- 第 3 步 - 将 CustomCommands 拖到此窗体上,以便您拥有数据库中的所有文本框。重命名标签,以免忘记哪个文本框链接到哪个内容(这将帮助您保持条理)。
第四部分 – 完善 Form1 代码
本部分目标
在本部分中,我们将介绍
- Form1 的代码
- Form4 的代码
Form1 的代码
/****************************************************************************
* Author: Matthew Mansfield *
* Date: 06/13/2013 *
* Description: The purpose of this C# programming is to create a voice *
* recognition application that can provide text to speech *
* responses to speech to text commands. *
*****************************************************************************
*/
//---------------------------------------------------------------------------
//Using directives - This section lists the namespaces that the application
//will be using frequently, and saves the programmer from specifying a fully
//qualified name every time that a method that is contained within is used.
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Speech.Recognition;
//---------------------------------------------------------------------------
//Declare namespace
//---------------------------------------------------------------------------
namespace DATABASING
{
//-----------------------------------------------------------------------
//Begin the class
//-----------------------------------------------------------------------
public partial class Form1 : Form
{
//-------------------------------------------------------------------
//Do this to initialize
//-------------------------------------------------------------------
public Form1()
{
InitializeComponent();
}
//-------------------------------------------------------------------
//For our purposes, we are not using this but this is basic
//navigator binding
//-------------------------------------------------------------------
private void customCommandsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.customCommandsBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.vRDataSet);
}
//-------------------------------------------------------------------
//Load the basic database information, set focus to the given textbox
//as well as running the FillingLists_method method
//-------------------------------------------------------------------
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the
//'vRDataSet.CustomCommands' table. You can move, or remove it,
//as needed.
this.customCommandsTableAdapter.Fill(this.vRDataSet.CustomCommands);
this.customCommandsBindingSource.AddNew();
this.commonFieldTextBox.Focus();
FillingLists_method();
}
//-------------------------------------------------------------------
//When a command is given we need to find out where it is "located"
//in the database. This helps us to find the location of the database
//entry
//-------------------------------------------------------------------
private void textBox3_TextChanged_1(object sender, EventArgs e)
{
int loc = customCommandsBindingSource.Find("Result", this.textBox3.Text);
customCommandsBindingSource.Position = loc;
}
//-------------------------------------------------------------------
//Close this Form when this button is pressed
//-------------------------------------------------------------------
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
//-------------------------------------------------------------------
//When we leave this Form, do this
//-------------------------------------------------------------------
private void Form2_Leave(object sender, EventArgs e)
{
this.Close();
}
//-------------------------------------------------------------------
//Establishing the get set
//-------------------------------------------------------------------
public bool visible { get; set; }
//-------------------------------------------------------------------
//Main method we run to take results from what the user searches for
//and places it into the result textbox
//-------------------------------------------------------------------
public void runcode_method()
{
if (this.resultTextBox1.Text == "")
{
}
else
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = resultTextBox1.Text;
p.Start();
//sleep for 1500ms
System.Threading.Thread.Sleep(1500);
//clear all textboxes
this.commandTextBox.Text = "";
this.resultTextBox.Text = "";
this.txtProfileName.Text = "";
this.resultTextBox1.Text = "";
//set focus here
this.commandTextBox.Focus();
}
}
//-------------------------------------------------------------------
//When a command is given we need to find out where it is "located"
//in the database. This helps us to find the location of the database
//entry and set the position of the binding source to it
//(the next few methods are the same)
//-------------------------------------------------------------------
public void find_method()
{
int loc = customCommandsBindingSource.Find("Command", this.toolStripTextBox1.Text); customCommandsBindingSource.Position = loc;
}
//-------------------------------------------------------------------
//When a command is given we need to find out where it is "located"
//in the database. This helps us to find the location of the database
//entry and set the position of the binding source to it
//-------------------------------------------------------------------
public void checkingValue_method()
{
int loc = customCommandsBindingSource.Find("Command", this.commandTextBox.Text);
customCommandsBindingSource.Position = loc;
}
//-------------------------------------------------------------------
//When a command is given we need to find out where it is "located"
//in the database. This helps us to find the location of the database
//entry and set the position of the binding source to it
//-------------------------------------------------------------------
private void toolStripButton1_Click(object sender, EventArgs e)
{
int loc = customCommandsBindingSource.Find("Command", this.toolStripTextBox1.Text);
customCommandsBindingSource.Position = loc;
}
//-------------------------------------------------------------------
//Saves the database and then moves to the next available field
//in the database
//-------------------------------------------------------------------
private void btnSave_Click(object sender, EventArgs e)
{
this.customCommandsBindingNavigatorSaveItem.PerformClick();
this.customCommandsBindingSource.AddNew();
this.customCommandsBindingSource.MoveLast();
this.toolStripTextBox1.Text = "";
this.btnOpen.Visible = false;
this.radioButton1.Checked = false;
this.radioButton2.Checked = false;
this.commandTextBox.Focus();
}
//-------------------------------------------------------------------
//If the user wants the system to open a webpage they can select this
//then this text will be inserted to the correct textbox
//-------------------------------------------------------------------
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButton1.Checked == true)
{
this.btnOpen.Visible = false;
this.resultTextBox.Text = "http://www.";
this.resultTextBox.Focus();
}
}
//-------------------------------------------------------------------
//Run a quick check for the radio buttons
//-------------------------------------------------------------------
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (this.radioButton2.Checked == true)
{
this.btnOpen.Visible = true;
this.resultTextBox.Text = "";
}
}
//-------------------------------------------------------------------
//Open up a dialog box if the user selects to open a program. This is
//set to default to the C:\ drive
//-------------------------------------------------------------------
private void btnOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.IO.StreamReader sr = new
System.IO.StreamReader(openFileDialog1.FileName);
this.openFileDialog1.InitialDirectory = @"C:\";
sr.Close();
//Place the results to this textbox
this.resultTextBox.Text = (openFileDialog1.FileName.ToString());
}
}
//-------------------------------------------------------------------
//If the user is attempting to place a duplicate entry for something
//the system will create a message that pops up and lets them know.
//This is to save you heart ache in the future. No person can serve
//to masters and in the same no command can server two functions ;)
//-------------------------------------------------------------------
private void commandTextBox_Leave(object sender, EventArgs e)
{
int loc = customCommandsBindingSource.Find("Command", this.commandTextBox.Text);
if (loc != -1)
{
MessageBox.Show("This is a duplicate entry, please try another word/phrase.", "Data Entry Error");
this.commandTextBox.Text = "";
this.commandTextBox.Focus();
}
}
//-------------------------------------------------------------------
//Reference to this method
//-------------------------------------------------------------------
private void btnToListbox_Click(object sender, EventArgs e)
{
FillingLists_method();
}
//-------------------------------------------------------------------
//Pretty basic method here
//-------------------------------------------------------------------
private void FillingLists_method()
{
this.listBox1.DataSource = customCommandsBindingSource;
this.listBox1.DisplayMember = "Command";
this.listBox2.DataSource = customCommandsBindingSource;
this.listBox2.DisplayMember = "Result";
this.listBox3.DataSource = customCommandsBindingSource;
this.listBox3.DisplayMember = "CommonField";
}
//-------------------------------------------------------------------
//Create an instance of the SpeechSynthesizer named "synth"
//-------------------------------------------------------------------
SpeechSynthesizer synth = new SpeechSynthesizer();
//-------------------------------------------------------------------
//Create an instance of the SpeechRecognitionEngine called "sre"
//-------------------------------------------------------------------
SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
//-------------------------------------------------------------------
//Create Speech Timer
//-------------------------------------------------------------------
Timer speechTimer = new Timer();
//-------------------------------------------------------------------
//Speak: Takes in a string. Then outputs the string as Speech
//-------------------------------------------------------------------
public void Speak(string text)
{
//Speak text
synth.Speak(text);
}
//-------------------------------------------------------------------
//Set the SpeechRate of the Speaker
//-------------------------------------------------------------------
public int SpeechRate
{
//Value range is -10 to 10
//Default is 0
get { return synth.Rate; }
set { synth.Rate = value; }
}
//-------------------------------------------------------------------
//Starts instance of speech recognition
//-------------------------------------------------------------------
public void StartDefaultRecognition()
{
string[] words = new string[this.listBox1.Items.Count];
StartCustomRecognition(words);
}
//---------------------------------------------------------------
//Create an instance of the SpeechSynthesizer named "synth"
//---------------------------------------------------------------
private void sendingtoarray_method()
{
string[] words = new string[this.listBox1.Items.Count];
}
//-------------------------------------------------------------------
//Called to stop Speech Engine
//-------------------------------------------------------------------
public void StopRecognition()
{
//Stop Speech Recognition Engine
sre.RecognizeAsyncStop();
}
//-------------------------------------------------------------------
//Called to setup new grammer
//-------------------------------------------------------------------
public void StartCustomRecognition(String[] words)
{
//Stop any running instances
StopRecognition();
//Set input to default audio device
sre.SetInputToDefaultAudioDevice();
//Create a grammer builder instance called grammerBuilder
GrammarBuilder grammarBuilder = new GrammarBuilder();
grammarBuilder.Append(new Choices(words));
//Create a grammer instance called customGrammer that uses the grammer
//created from GrammerBuilder called "grammerBuilder"
Grammar customGrammar = new Grammar(grammarBuilder);
//Unload past grammer and set new grammer
sre.UnloadAllGrammars();
sre.LoadGrammar(customGrammar);
//Create SpeechRecognized Event
sre.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sre_Listen);
}
//-------------------------------------------------------------------
//Called to listen for one command
//-------------------------------------------------------------------
public void StartListening()
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.SoundLocation = @"audio/b1.wav";
player.Play();
sre.RecognizeAsync(RecognizeMode.Multiple);
speechTimer.Tick += new EventHandler(speechTimer_Tick);
speechTimer.Interval = 5000;
speechTimer.Enabled = true;
speechTimer.Start();
}
//-------------------------------------------------------------------
//Stop Listening after set time
//-------------------------------------------------------------------
void speechTimer_Tick(object sender, EventArgs e)
{
StopRecognition();
speechTimer.Enabled = false;
speechTimer.Stop();
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.SoundLocation = @"audio/b1.wav";
player.Play();
}
//------------------------------------------------------------------
//Called when word is detected. Passes action onto SpeechList Class
//-------------------------------------------------------------------
void sre_Listen(object sender, SpeechRecognizedEventArgs e)
{
//Stop Listening
StopRecognition();
//Stop Timer
speechTimer.Enabled = false;
speechTimer.Stop();
}
}
}
Form4 的代码
/****************************************************************************
* Author: Matthew Mansfield *
* Date: 06/13/2013 *
* Description: The purpose of this C# programming is to create a voice *
* recognition application that can provide text to speech *
* responses to speech to text commands. *
*****************************************************************************
*/
//---------------------------------------------------------------------------
//Using directives - This section lists the namespaces that the application
//will be using frequently, and saves the programmer from specifying a fully
//qualified name every time that a method that is contained within is used.
//---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using SpeechLib;
using MouseKeyboardLibrary;
using System.Speech.Synthesis;
using System.Speech.Recognition;
using System.Collections;
//---------------------------------------------------------------------------
//Declare namespace
//---------------------------------------------------------------------------
namespace DATABASING
{
//-----------------------------------------------------------------------
//Begin the class
//-----------------------------------------------------------------------
public partial class Form4 : Form
{
//-------------------------------------------------------------------
//Create an instance of the SpeechSynthesizer named "synth"
//-------------------------------------------------------------------
SpeechSynthesizer synth = new SpeechSynthesizer();
//-------------------------------------------------------------------
//Create an instance of the SpeechRecognitionEngine called "sre"
//-------------------------------------------------------------------
SpeechRecognitionEngine sre = new SpeechRecognitionEngine();
//-------------------------------------------------------------------
//SAPI Object Classes
// - Declaring SAPI Application Object Classes
//-------------------------------------------------------------------
private SpeechLib.SpSharedRecoContext objRecoContext;
private SpeechLib.ISpeechRecoGrammar grammar;
//-------------------------------------------------------------------
//Assigning string as variable
//-------------------------------------------------------------------
private string strData = "No recording yet";
//-------------------------------------------------------------------
//Do this to initialize
//-------------------------------------------------------------------
public Form4()
{
InitializeComponent();
}
//-------------------------------------------------------------------
//***** This is hidden because the Form is too small to fit it ******
//Should this button be pressed run our Try-Catch
//-------------------------------------------------------------------
private void button1_Click(object sender, EventArgs e)
{
try
{
if (objRecoContext == null)
{
objRecoContext = new SpeechLib.SpSharedRecoContext();
objRecoContext.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(RecoContext_Recognition);
grammar = objRecoContext.CreateGrammar(1);
grammar.DictationLoad("", SpeechLoadOption.SLOStatic);
}
grammar.DictationSetState(SpeechRuleState.SGDSActive);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Exception caught when initializing SAPI." + " This application may not run correctly.\r\n\r\n" + ex.ToString(), "Error");
}
}
//-------------------------------------------------------------------
//***** This is hidden because the Form is too small to fit it ******
//-------------------------------------------------------------------
private void button2_Click(object sender, EventArgs e)
{
grammar.DictationSetState(SpeechRuleState.SGDSInactive);
}
public void RecoContext_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
{
strData = Result.PhraseInfo.GetText(0, -1, true);
Debug.WriteLine("Recognition: " + strData + ", " + StreamNumber + ", " + StreamPosition);
textBox1.Text = strData; //strData = strData;
}
//-------------------------------------------------------------------
//***** This is hidden because the Form is too small to fit it ******
//This was used to save as a wav file but the function has not been
//used since the early days of this program. This code used to work
//but a lot of changes have been made and it may not work anymore.
//You are welcome to play with it if you find you may use some of it.
//-------------------------------------------------------------------
private void button3_Click(object sender, EventArgs e)
{
try
{
SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
SpVoice Voice = new SpVoice();
if (checkBox1.Checked)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "All files (*.*)|*.*|wav files (*.wav)|*.wav";
sfd.Title = "Save to a wave file";
sfd.FilterIndex = 2;
sfd.RestoreDirectory = true;
if (sfd.ShowDialog() == DialogResult.OK)
{
SpeechStreamFileMode SpFileMode = SpeechStreamFileMode.SSFMCreateForWrite;
SpFileStream SpFileStream = new SpFileStream();
SpFileStream.Open(sfd.FileName, SpFileMode, false); Voice.AudioOutputStream = SpFileStream;
Voice.Speak("You recorded the following message " + strData, SpFlags);
Voice.WaitUntilDone(Timeout.Infinite);
SpFileStream.Close();
}
}
else
{
Voice.Speak("You recorded the following message" + strData, SpFlags);
}
}
catch
{
MessageBox.Show("Speak error", "SimpleTTS", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//-------------------------------------------------------------------
//For our purposes, we are not using this but this is basic
//navigator binding
//-------------------------------------------------------------------
private void customCommandsBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.customCommandsBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.vRDataSet);
}
//-------------------------------------------------------------------
//This loads the "connection" to the database and populates the table
//-------------------------------------------------------------------
private void Form4_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'vRDataSet.CustomCommands' table. You can move, or remove it, as needed.
this.customCommandsTableAdapter.Fill(this.vRDataSet.CustomCommands);
button1_Click(sender, e);
}
//-------------------------------------------------------------------
//This is the "D.B." button
//-------------------------------------------------------------------
private void button4_Click(object sender, EventArgs e)
{
Form1 form = new Form1();
form.Show();
}
//-------------------------------------------------------------------
//When a change happens, keep the focus
//-------------------------------------------------------------------
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.textBox1.Focus();
find_method();
}
//-------------------------------------------------------------------
//This searches for the matching command in the database
//-------------------------------------------------------------------
public void find_method()
{
int loc = customCommandsBindingSource.Find("Command", this.textBox1.Text);
customCommandsBindingSource.Position = loc;
}
//-------------------------------------------------------------------
//When the text is changed in the "resultant" text box run this
//method. This is what actually makes the computer speak anything to
//you.
//-------------------------------------------------------------------
private void resultTextBox_TextChanged(object sender, EventArgs e)
{
runcode_method();
}
//-------------------------------------------------------------------
//This method speaks the matching text, pauses and then resets the
//input textbox by setting it to ""
//-------------------------------------------------------------------
public void runcode_method()
{
if (this.resultTextBox.Text == "")
{
}
else
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
// p.StartInfo.WorkingDirectory = Path.GetDirectoryName(path);
p.StartInfo.FileName = resultTextBox.Text;
p.Start();
System.Threading.Thread.Sleep(1500);
this.textBox1.Text = "";
this.resultTextBox.Text = "";
this.textBox1.Focus();
}
}
//-------------------------------------------------------------------
//A quick and dirty conversion of text to speech
//-------------------------------------------------------------------
void speakbox()
{
Convert.ToString(commonFieldTextBox.Text);
Speak(commonFieldTextBox.Text);
}
//-------------------------------------------------------------------
//Take string text and turn it into a speech using the "synth"
//that was initialized earlier using SpeechSynthesizer
//-------------------------------------------------------------------
public void Speak(string text)
{
synth.Speak(text);
}
//-------------------------------------------------------------------
//This uses the speakbox method to take the data in the
//commonFieldTextbox and turn it to speech
//-------------------------------------------------------------------
private void commonFieldTextBox_TextChanged_1(object sender, EventArgs e)
{
speakbox();
}
//-------------------------------------------------------------------
//When text is changed in this textbox then run this method
//-------------------------------------------------------------------
private void resultTextBox_TextChanged_1(object sender, EventArgs e)
{
runcode_method();
}
//-------------------------------------------------------------------
//This button is not visible but still can be accessed if needed.
//This simply runs a batch file.
//-------------------------------------------------------------------
private void button5_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("D:\\VR_MAIN\\VR1\\DATABASING current version\\DATABASING\\OpenDB.bat");
}
}
}
第五部分 – 附加功能和特性
本部分目标
在本部分中,我们将介绍
- 更多想法
- 批处理文件
- VBScript 脚本
- 自动化家电
- 项目下载
- 结论
更多想法
此时,您的程序应该可以正常运行了。我们已经涵盖了程序的各个方面,直至代码。当然,您接下来如何使用您的新 VR 程序取决于您,但我或许可以提出一些建议,这些建议可能会在您探索许多可以增强贾维斯体验的有趣事物时有所帮助。在接下来的部分中,我将不解释如何执行这些操作,而是简单地给您一些可以作为基础的想法。
批处理文件
如果您不熟悉批处理文件,它们基于 MS-DOS,由 Windows 于 1985 年推出,并且仍然非常有效。使用您的新 VR 程序,您可以执行批处理文件,这些文件可以极大地帮助自动化任务。例如,如果您希望您的 VR 程序向您发送电子邮件,您可以编写一个批处理文件来完成此任务,并借助 BLAT for Windows。
VBScript 脚本
VBScript(Visual Basic Scripting Edition)是 Microsoft 开发的一种脚本语言,它为您的 VR 应用程序提供了一些非常有用的功能。例如,您可以通过创建一个文本文件并保存以下文本来轻松创建一个 VBScript:
Set objVoice = CreateObject("SAPI.SpVoice")
objVoice.Speak (FormatDateTime(Date(), 1))
如果您将文件扩展名从 .txt 更改为 .vbs,您现在将拥有一个文件,单击后它会告诉您当前日期。因此,以下代码将告诉您时间:
Set objVoice = CreateObject("SAPI.SpVoice")
objVoice.Speak (Time())
使用这些脚本可以为您的应用程序带来一些非常酷的元素,并有助于激发您的创造力。VBScripts 的优点在于它们极其易于创建,代码简单,但运行起来却极其强大。此外,使用您的新 VR 应用程序时,当您将应用程序设置为 .vbs 文件时,它将像可执行文件一样启动。
自动化家电
仅仅因为您有一个 VR 程序,并不意味着您的灯会自动打开/关闭,只需您说句话就行了。您需要将控件连接到您的设备,然后将这些控件连接到您的 VR 应用程序。要控制一个应用程序,例如一盏灯,您必须控制输送给它的电。作为建议,我建议研究一下 Parallax Microcontrollers,它允许您控制设备的开关(或灯)。用于 Parallax Microcontrollers 的语言称为 Basic Stamp,通过一些研究,您可以将所有的灯连接到您的 VR 程序,并随着您的声音而工作。
项目下载
这是您可以下载的 zip 文件,以便亲眼看看代码是如何工作的:VR 下载
结论
在我第一次编程时,我有很多疑问,很多时候我只是希望我能看到一个实际运行的程序的代码。我希望本教程能为您解答许多疑问,并希望您喜欢这次创建您自己的 C# VR 程序的 walkthrough。