How do I make my program ask for confirmation when using a speech command?

356 views Asked by At

I have a small voice commanding program that I am working on and I would like to make it ask for confirmation when given certain command... Like "hey computer, close program" followed by the verbal question "Are you sure?" and after that responding to my verbal answer; yes or no. I am fairly new to c# and couldn't find anything related. The following code is an example of voice commands that I already configured:

private void recEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    switch (e.Result.Text)
    {                
        case "hey computer, start spotify":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("starting SPOTteFY");
            string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string extentionToPath = "Spotify\\Spotify.exe";
            string finalPath = Path.Combine(appDataPath, extentionToPath);

            Process.Start(finalPath);
            //Process.Start("C:\\Users\\Danny\\AppData\\Roaming\\Spotify\\Spotify.exe");
            break;
        case "hey computer, start chrome":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("Starting Chrome");
            Process.Start("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe");
            break;
        case "hey computer, new tab":
            SendKeys.Send("^t");
            break;
        case "hey computer, close program":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("Closing program");
            SendKeys.Send("%{F4}");
            break;
        case "next song please":
            keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);
            break;
        case "stop song please":
            keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);
            break;
        case "hey computer, start netflix":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("Starting Netflix");
            System.Diagnostics.Process.Start("https://www.netflix.com/browse");
            break;
        case "hey computer, pause netflix":
            SendKeys.Send(" ");
            break;
        case "hey computer, start reddit":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("Starting reddit");
            System.Diagnostics.Process.Start("https://www.reddit.com");
            break;
        case "hey computer, show me the news":
            synthesizer.SelectVoiceByHints(VoiceGender.Female);
            synthesizer.SpeakAsync("Showing you what's going on");
            System.Diagnostics.Process.Start("http://nu.nl");
            break;

        case "hey computer, hide yourself":
            this.WindowState = FormWindowState.Minimized;
            break;
    }
}
1

There are 1 answers

0
Teneko On

You can before you execute the command (you spoke), run an event and ask for permission. But be aware this solution works with an user interface. For antoher solution look at option 2.

Option 1:

    public SomeClass() {
            PermissionEvent += this_PermissionEvent;
            }

            private void this_PermissionEvent(object sender, PermissionEventArgs args) {
        // MessageBox.Show(...) waits until you closed the window (yes/no/closed/terminated)
            if (MessageBox.Show("Do you want execute?","Grant Permission",MessageBoxButtons.YesNo) == DialogResult.Yes) {
        args.Handle = true;
        }
            }

            private event EventHandler<PermissionEventArgs> PermissionEvent;

            private void recEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
            {
            switch (e.Result.Text)
            {                
            case "hey computer, start spotify":
            //
            var args = new PermissionEventArgs();
    // args is a reference type. That means, when you change args.Handle in this_PermissionEvent(...) then this args.Handle is also changed.
            PermissionEvent?.Invoke(args)

    // here we check the condition that might be changed.
            if (args.Handle) {
            // do something here
            }
            break;
            }
            }

            public class PermissionEventArgs : EventArgs {
            public bool Handle = false
            }

This is one is a solution where the feedback can happen synchonously without working with a list, a kind of history.

When you want that way with answering to "Are you sure?", you can work with a list. That means, you start a command and puts it with the information about this command in in a list and runs immediately a funtion that reads the entries of the list. Now you should play with the information about these commands, remove invalid entries, executes functions when they are true and so on.

Here a small example:

Option 2:

         List<Entry> list; // This list contains the commands

            public SomeClass() {
            list = new List<Entry>(); // initializion of the list in the constructor
            }

            private void verifyList() {
            if (list.Count == 0)
            return;

            if (list[0].Cmd == Command.Yes || list[0].Cmd == Command.No) {
            list.Clear();
            } else if (!list[0].NeedConfirm || (list.Count == 2 && list[1].Cmd == Command.Yes)) {
            list[0].Call?.Invoke();
            list.Clear();
            } else if (list.Count >= 2) {
            list.Clear();
            }
            }

            private void recEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
            {
                switch (e.Result.Text)
                {                
                    case "hey computer, start spotify":
            list.Add(new Entry() { Cmd = Command.Yes, Call = new Action(() => {
            // start spotify
            }) });
            verifyList();
                        break;
                    case "confirm command": 
            list.Add(new Entry() { Cmd = Command.Yes });
            verifyList();
            break;
 case "do not confirm command": 
            list.Add(new Entry() { Cmd = Command.No });
            verifyList();
            break;
            }
            }

    // This class holds all important stuff of one command. 
    // 1. The kind of command
    // 2. the action that performs if condition in verifyList() are true
    // 3. And NeedConfirm that the verifiyList() needs
        public class Entry {
        Command Cmd;
        Action Call;
        bool NeedConfirm;
        }

        public enum Command {
        StartSpotify,
        Yes,
        No
        }