首页 > 解决方案 > 努力使用我的语音识别应用程序 c# 添加后续功能

问题描述

所以例如我说“播放下一首歌”,我的应用程序这样做了,我想要一个功能,它只为“再听一次”这个词再次开始听 3 秒钟,这样它就可以再跳过一次,然后再听 3 秒钟,如果 3 秒过去了,我希望循环语句关闭。

这是我试过的”:

        private async void Default_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
         string speech = e.Result.Text;
         switch (speech)
         {
             case "play next":
                    Speak.SpeakAsync("playing next");
                    keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); //this line is just my "play next" function.
                    _next_song.RecognizeAsync(RecognizeMode.Multiple); //this line enables a different voice recognition function.
                    break;
         }



//void to continue next song again
        private async void _next_song_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            string speech = e.Result.Text;
            _recognizer.RecognizeAsyncStop(); //this is my main recognizer that contains all the commands
            while (true)
            {
                if (speech == "one more")
                {
                    Speak.SpeakAsync("sure");
                    keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);
                    return;

                }
                await Task.Delay(3000);
                break;
            }
            _next_song.RecognizeAsyncCancel();
            _recognizer.RecognizeAsync(RecognizeMode.Multiple);

        }

问题是,我的代码工作,只是不是我想要的方式,当我说“播放下一首”时,它会播放下一首歌曲并等待我说“再一次”跳过一次并再次开始收听,它只是3 秒后不会断链,只有当它听到其他声音时,然后 3 秒后,它才会返回主 _recognizer 识别功能。

无论如何,我可以在不使用不同的 SpeechRecognition Module 的情况下实现后续命令?非常感谢任何帮助!

标签: c#speech-recognition

解决方案


如果我理解你的问题,我会提出一个解决方案,所以我认为你不需要使用两个识别器:我只使用一个 int 来捕获阶段和线程来执行循环..

    //directives needed for thread
    using System.Threading;
    using System.Threading.Tasks;
    //--------------------------
    public int phase;
    public bool onemore;
    public bool running;
    private Thread thread;

    public readonly AutoResetEvent _signalGo = new AutoResetEvent(false);

    //To put in the constructor of the class
    thread = new Thread(new ThreadStart(loop));

    private void speechRecognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
        string speech = e.Result.Text;
        lblDemo.Content = speech;
        switch (speech)
        {
            case "play next":
                if (phase != 0) return;
                if (!running)
                    thread.Start();
                else
                    _signalGo.Set();

                Speak.SpeakAsync("playing next");
                keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);
                break;
            case "one more":
                if (phase != 1) return;
                onemore = true;
                Speak.SpeakAsync("sure");

                break;
        }
    }

    public async void loop()
    {
        running = true;
        while (running)
        {
            phase = 1;
            await Task.Delay(3000);
            //if sou say onemore=true, enter in loop
            while(onemore)
            {
                    onemore = false;

                //if you say again onemore before end of 3s, so reloop
                keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);
                await Task.Delay(3000);
            } 

            phase = 0;

            if (!running) break;
            _signalGo.WaitOne();//wait _signalGo.set() to continue
            if (!running) break;
        }
    }

        //Dont forget to dispose the resources at the end of program
       // for eaxmple in the destructor
       // if your class is named toto
       //destructor is ~toto
  public class toto
  {
       //constructor
       public toto()
       {
       }

       //destructor
       ~toto()
       {
         _signalGo.Set();
         running = false;

         _signalGo.Dispose();
         speechRecognizer.Dispose();
       }
   }

推荐阅读