Speech recognition in Windows application - c#

Here is my code:
private void button1_Click(object sender, EventArgs e)
{
SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine();
Grammar dictationGrammar = new DictationGrammar();
recognizer.LoadGrammar(dictationGrammar);
try
{
button1.Text = "speak now";
recognizer.SetInputToDefaultAudioDevice();
RecognitionResult result = recognizer.Recognize();
textBox1.Text = result.Text;
}
catch (InvalidOperationException exception)
{
textBox1.Text = String.Format("Could not recognize input from default audio device.Is a microphone or sound card available?\r\n{0} - {1}.", exception.Source, exception.Message);
}
finally
{
recognizer.UnloadAllGrammars();
}
}
Here it is not recognizing the exact word what am giving from microphone.It s taking another word,which is not meaningfull. How to rectify this problem?

Related

Serial Communication (C# Windows Forms)

Okay so I'm trying to do a two-way communication from C# to Arduino (using FTDI232) and viceversa, from Arduino to C#.
Here's the code:
public partial class Form1 : Form
{
public SerialPort myPort;
private DateTime dateTime;
private string inData;
const string com = "COM8";
public Form1()
{
InitializeComponent();
}
private void start_btn_Click(object sender, EventArgs e) // TURN ON LED
{
myPort = new SerialPort();
myPort.BaudRate = 9600;
myPort.PortName = com;
try
{
myPort.Open();
myPort.WriteLine("A");
myPort.Close();
error_tb.Text = "";
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Errore");
}
}
private void stop_btn_Click(object sender, EventArgs e) // TURN OFF LED
{
myPort = new SerialPort();
myPort.BaudRate = 9600;
myPort.PortName = com;
try
{
myPort.Open();
myPort.WriteLine("B");
myPort.Close();
error_tb.Text = "";
}
catch (Exception exc2)
{
MessageBox.Show(exc2.Message, "Error");
}
}
void MyPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
inData = myPort.ReadLine();
this.Invoke(new EventHandler(displayData_event));
}
private void displayData_event(object sender, EventArgs e)
{
dateTime = DateTime.Now;
string time = dateTime.Hour + ":" + dateTime.Minute + ":" + dateTime.Second;
values_tb.Text = time + "\t\t\t\t\t" + inData;
}
private void Form1_Load(object sender, EventArgs e) // PRESS PHYSICAL BUTTON TO SEND DATA
{
myPort = new SerialPort();
myPort.BaudRate = 9600;
myPort.PortName = com;
myPort.Parity = Parity.None;
myPort.DataBits = 8;
myPort.StopBits = StopBits.One;
myPort.DataReceived += MyPort_DataReceived;
try
{
myPort.Open();
values_tb.Text = "";
}
catch (Exception exc3)
{
MessageBox.Show(exc3.Message, "Error");
}
}
private void exit_btn_Click(object sender, EventArgs e) // Exit from Application
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
try
{
myPort.Close();
}
catch (Exception exc4)
{
MessageBox.Show(exc4.Message, "Error");
}
}
}
I have three problems. One is when I want to close the application, I want the Serial Communication to turn off, because I made it automatically open using Form1_Load, as soon as you start the debug, it also opens Serial Communication, and it remains on, but I don't want to use a button that I have to click first to close the application. I need to close Serial Communication automatically after I close the application.
The second problem is with the Serial Port that denies the communication, what I mean is that I need to switch from Receiving Data to Sending Data. Here's a picture of what it looks like: Application Image
The the third problem is the LED one. Well its similar to the second one, but this time when I click the button OFF, I want it to switch back to Receiving Data. Here's the picture:
Application Image 2
EDIT : This code is only temporary. I needed it to turn off the Serial Communication
private void button2_Click(object sender, EventArgs e)
{
try
{
myPort.Close();
}
catch (Exception exc4)
{
MessageBox.Show(exc4.Message, "Error");
}
}
You are initializing and opening the port many times. This is not allowed. Use a single initialization and keep the member. This makes the code much smoother, too.
public partial class Form1 : Form
{
public SerialPort myPort;
private DateTime dateTime;
const string com = "COM8";
public Form1()
{
InitializeComponent();
}
private void start_btn_Click(object sender, EventArgs e) // TURN ON LED
{
try
{
myPort.WriteLine("A");
error_tb.Text = "";
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Errore");
}
}
private void stop_btn_Click(object sender, EventArgs e) // TURN OFF LED
{
try
{
myPort.WriteLine("B");
error_tb.Text = "";
}
catch (Exception exc2)
{
MessageBox.Show(exc2.Message, "Error");
}
}
void MyPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var inData = myPort.ReadLine(); // Use local variable
Invoke(new Action<string>(displayData_event), inData);
}
private void displayData_event(string data)
{
dateTime = DateTime.Now;
string time = dateTime.Hour + ":" + dateTime.Minute + ":" + dateTime.Second;
values_tb.Text = time + "\t\t\t\t\t" + data;
}
private void Form1_Load(object sender, EventArgs e) // PRESS PHYSICAL BUTTON TO SEND DATA
{
myPort = new SerialPort();
myPort.BaudRate = 9600;
myPort.PortName = com;
myPort.Parity = Parity.None;
myPort.DataBits = 8;
myPort.StopBits = StopBits.One;
myPort.DataReceived += MyPort_DataReceived;
try
{
myPort.Open();
values_tb.Text = "";
}
catch (Exception exc3)
{
MessageBox.Show(exc3.Message, "Error");
}
}
private void exit_btn_Click(object sender, EventArgs e) // Exit from Application
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
try
{
myPort.Close();
myPort = null;
}
catch (Exception exc4)
{
MessageBox.Show(exc4.Message, "Error");
}
}
}
I think I also fixed your event handling. One handler that gets the data and then forwards the received text is enough. You would also not really require the exception handling around WriteLine now, since that cannot really fail.

Writing and closing Notepad++ using speech recognition libraries

I'm trying to write code that will open Notepad++, write to a file, and close it afterward. My code is included below. I'm totally new to C#. Is there any library or way to do this?
// Button Reference
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.Equals("Enable Voice Control"))
{
button1.Text = "Stop Voice Control";
recEngine.RecognizeAsync(RecognizeMode.Multiple);
}
else
{
button1.Text = "Enable Voice Control";
recEngine.RecognizeAsyncStop();
}
}
public void Form1_Load(object sender, EventArgs e)
{
Choices commands = new Choices();
commands.Add(myCommands);
GrammarBuilder gBuilder = new GrammarBuilder();
gBuilder.Append(commands);
Grammar grammar = new Grammar(gBuilder);
recEngine.LoadGrammarAsync(grammar);
recEngine.SetInputToDefaultAudioDevice();
recEngine.SpeechRecognized += recEngine_SpeechRecognized;
}
void recEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
Process cmd = new Process();
cmd.StartInfo.FileName = #"notepad++.exe" ;
//cmd.StartInfo.Arguments =#"\Write.txt";
cmd.Start();
cmd.CloseMainWindow();
cmd.WaitForExit();
cmd.Refresh();
//if (cmd.StandardError != null)
//Console.WriteLine(cmd.StandardError.ReadToEnd());
var result = e.Result;
var i = 0;
foreach (var command in myCommands)
{
if (command.StartsWith("close"))
{
this.Close();
//cmd.StartInfo.FileName = #"notepad++";
cmd.Kill();
}
if (command.StartsWith("--") || command == string.Empty) continue; // Skip commentBlocks and skipEmptylines
var parts = command.Split(new char[] { '|' }); // Split the lines
i++;
if (command.Equals(result.Text))
{
Console.WriteLine("Command is {0}: {1}", i, command);
break;
}
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
You need not open notepad and write to file. You can do it programmarically.
// Create a file to write to.
string createText = "Hello and Welcome" + Environment.NewLine;
File.WriteAllText(path, createText);
// Open the file to read from.
string readText = File.ReadAllText(path);
You can use the below code to close the notepad:
Process[] processes = Process.GetProcessesByName("notepad");
foreach (var process in processes)
{
process.Kill();
}
It will close all instances of notepad. So better be sure the notepads are only that of yours (opened by your speech recognition program)
If you actually do not want to open notepad and your requirement is just to capture text and write to file programatically, then use the below code:
// Create a file to write to.
string createText = "Hello World"; // Replace with voice captured text
File.WriteAllText(path, createText);
// Open the file to read from.
string readText = File.ReadAllText(path);

Conversation with C# Speech Library

I have the following code using the Speech Recognition library:
var listen = new SpeechRecognitionEngine();
var reader = new Choices(File.ReadLines(#"C:\words.txt")
listen.LoadGrammar(new Grammar(new GrammarBuilder(reader)));
listen.SpeechRecognized += listen_SpeechRecognized;
listen.SpeechRecognitionRejected += listen_SpeechRecognitionRejected;
listen.SetInputToDefaultAudioDevice();
listen.RecognizeAsync(RecognizeMode.Multiple);
And I have an event listener like this...
static void listen_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
var talk = new SpeechSynthesizer();
if (e.Result.Text == "Search Stock Symbol")
{
talk.Speak("What symbol?");
//Do I have to create another event listener?
//a Listener .. symbol = a.Result.Text
//talk.Speak(GetQuote(symbol))
{
}
Would I have to create an event listener for every portion of the "conversation"? Is there a better way if that is the case?
Example Conversation:
Me: Search Stock Symbol
Computer: What Symbol?
Me: AAPL
Computer: Apple is trading at ....
Nope, just the one, then vary what you do depending on what text was received. In some code before:
List<string> stockSymbols = new List<string>();
stockSymbols.Add("AAPL");
Then
string lastSpeechInput;
static void listen_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
var talk = new SpeechSynthesizer();
switch (e.Result.Text) {
case "Search Stock Symbol":
talk.Speak("What symbol?");
break;
default:
break;
}
if (stockSymbols.Contains(e.Result.Text) && lastSpeechInput == "Search Stock Symbol") {
talk.Speak(getStockPrice(e.Result.Text);
}
lastSpeechInput = e.Result.Text;
}

Parse first word of the command in recognized speech

I am trying to take speech input and convert them to string and show it on the richtext box control. I have read about speech synthesis and voice recognition in several articles where I learned to get commands via speech however I want to write on richtext box control after my command Write is recognized. Is it possible?
Here is the code if it helps understand what I am trying to achieve and what I have done so far
object declarations
PromptBuilder pb = new PromptBuilder();
SpeechRecognitionEngine recognizer = new SpeechRecognitionEngine();
Choices clist = new Choices();
The code for Enabling Voice Input
private void btnEnableVoice_Click(object sender, EventArgs e)
{
btnEnableVoice.Enabled = false;
btnDisableVoice.Enabled = true;
/////////////Adding commands in a list of type Choices///////////////////////
clist.Add(new string[] { "Is it working", "Write" });
Grammar gr = new Grammar(new GrammarBuilder(clist));
try
{
recognizer.RequestRecognizerUpdate(); ///////starting engine
recognizer.LoadGrammar(gr);
recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
recognizer.SetInputToDefaultAudioDevice();
recognizer.RecognizeAsync(RecognizeMode.Multiple);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
switch (e.Result.Text.ToString())
{
case "Is it working":
ss.SpeakAsync("Yes its working");
break;
case "Write":
richTextBox1.Text += ""; //Speech to text input here
break;
}
}
First you need to construct a grammar in a proper way to allow dictation, see for the reference http://msdn.microsoft.com/en-us/library/ms576565(v=vs.110).aspx:
Choices clist = new Choices();
clist.Add(new string[] { "Is it working", "Write" });
GrammarBuilder bl = new GrammarBuilder(clist);
bl.appendDictation();
Grammar gr = new Grammar(bl);
To parse you need something like
void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
string result = e.Result.Text.ToString();
if (result.startsWith("Write")) {
richTextBox1.Text += result.substring(7); // Skip first 6 chars
} else if (result.startsWith("Is it working")) {
ss.SpeakAsync("Yes its working");
}
}

WP7 Skydrive API - creating folder doesnt work

I try this tutorial to create new folder on skydrive from my WP7 app.
Here is my code:
private void MSAccountLoginToggleSwitch_Checked_1(object sender, RoutedEventArgs e)
{
try
{
LiveAuthClient auth = new LiveAuthClient("** my id **");
auth.LoginAsync(new string[] { "wl.skydrive_update", "wl.calendars_update" });
auth.LoginCompleted += auth_LoginCompleted;
}
catch (LiveAuthException exception)
{
MessageBox.Show("Error signing in: " + exception.Message);
}
}
private void auth_LoginCompleted(object sender, LoginCompletedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
mySession = e.Session;
}
else
{
MSAccountLoginToggleSwitch.IsChecked = false;
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
try
{
var folderData = new Dictionary<string, object>();
folderData.Add("some test", "A brand new folder was created");
LiveConnectClient liveClient = new LiveConnectClient(mySession);
liveClient.PostAsync("me/skydrive", folderData);
}
catch (LiveConnectException exception)
{
MessageBox.Show("Error creating folder: " + exception.Message);
}
finally
{
MessageBox.Show("uploded");
}
}
it show me messagebox "uploaded", but when I look on my skydrive that file was not created.
It doesnt show any error message, what Im doing worng?
This line liveClient.PostAsync("me/skydrive", folderData); gives you a Task which you do not wait, you just show MessageBox.Show("uploded"); at the end. I don't think that async / await are supported in WP7, so you will need to handle Task with ContinueWith method:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var folderData = new Dictionary<string, object>();
folderData.Add("some test", "A brand new folder was created");
LiveConnectClient liveClient = new LiveConnectClient(mySession);
liveClient.PostAsync("me/skydrive", folderData)
.ContinueWith((t) =>
{
if (t.IsFauled)
{
MessageBox.Show("Error creating folder: " + t.Exception.Message);
}
else
{
MessageBox.Show("uploded");
}
}
, TaskScheduler.FromCurrentSynchronizationContext());
}
UPDATED: Code above will work only on WP8, but on WP7 PostAsync is not a method with Task, so to get PostAsync result you need to subscribe to PostCompleted event.
I found problem I have mistake in line:
folderData.Add("some test", "A brand new folder was created");
correct version is:
folderData.Add("name", "some test");
var folderData = new Dictionary<string,object>();
folderData.Add("myfolder ","simple folder ");
client.PostAsync("me/skydrive","{'name': 'myfolder' }");
client.PostCompleted += new EventHandler<LiveOperationCompletedEventArgs> (client_PostCompleted);
void client_PostCompleted(object sender, LiveOperationCompletedEventArgs e)
{
var a = e.RawResult;
}

Categories