音声認識アプリをC#コンソールアプリケーションで作ってみた。[Windows.Media.SpeechRecognition]

f:id:nakadasanda1:20200515105800p:plain

前回の続きcrtanaで使われている、音声認識をUWPで使った。
UWPは、Windowsの環境でwindowsのアプリストアから提供するしか方法がない、これでは利用が大きく制限されるので今度は、C#のデスクトップアプリ、exeファイルとして実行する方法について説明していきます。

nakadasanda.hatenablog.jp

UWPを使うことでwindows10で使うことができる(Cortanaや、windows10の通知機能など)などを多く使うことができます。ということで初めて行きます。

visual studioを起動してアプリケーションを作ります。

NugetでUWPapiを追加する。

f:id:nakadasanda1:20200515111631p:plain

Visual Studio で、 [ツール] -> [NuGet パッケージ マネージャー] -> [パッケージ マネージャー設定] の順にクリックします。
[既定のパッケージ管理形式] に [PackageReference] が選択されていることを確認します。

Visual Studio で、 [ツール] -> [NuGet パッケージ マネージャー] -> [パッケージ マネージャーの管理] の順にクリックします。
参照タブをクリックして探します。
Microsoft.Windows.SDK.Contractsをインストールします。

マイクの許可を申請します。 新しくプログラムを作成します。AudioCapturePermission.csという名前にします。

using System;
using System.Threading.Tasks;
using Windows.Media.Capture;

namespace Speech2
{
    class AudioCapturePermission
    {
        // If no microphone is present, an exception is thrown with the following HResult value.
        private static int NoCaptureDevicesHResult = -1072845856;

        /// <summary>
        /// Note that this method only checks the Settings->Privacy->Microphone setting, it does not handle
        /// the Cortana/Dictation privacy check.
        ///
        /// You should perform this check every time the app gets focus, in case the user has changed
        /// the setting while the app was suspended or not in focus.
        /// </summary>
        /// <returns>True, if the microphone is available.</returns>
        public async static Task<bool> RequestMicrophonePermission()
        {
            try
            {
                // Request access to the audio capture device.
                MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();
                settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
                settings.MediaCategory = MediaCategory.Speech;
                MediaCapture capture = new MediaCapture();

                await capture.InitializeAsync(settings);
            }
            catch (TypeLoadException)
            {
                // Thrown when a media player is not available.
                var messageDialog = new Windows.UI.Popups.MessageDialog("Media player components are unavailable.");
                await messageDialog.ShowAsync();
                return false;
            }
            catch (UnauthorizedAccessException)
            {
                // Thrown when permission to use the audio capture device is denied.
                // If this occurs, show an error or disable recognition functionality.
                return false;
            }
            catch (Exception exception)
            {
                // Thrown when an audio capture device is not present.
                if (exception.HResult == NoCaptureDevicesHResult)
                {
                    var messageDialog = new Windows.UI.Popups.MessageDialog("No Audio Capture devices are present on this system.");
                    await messageDialog.ShowAsync();
                    return false;
                }
                else
                {
                    throw;
                }
            }
            return true;
        }
    }
}

これでマイクの使用準備ができました。
メインのプログラムを書いていきます。
Program.csに追加します。

using System;
using Windows.Media.SpeechRecognition;

namespace Speech2
{
    class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>

        private static SpeechRecognizer contspeechRecognizer;
         static void Main()
        {
            Initialize();
            Console.ReadKey();
        }

        private static async void Initialize()
        {
            //初期化
            contspeechRecognizer = new SpeechRecognizer();
            await contspeechRecognizer.CompileConstraintsAsync();

            //認識中の処理
            contspeechRecognizer.HypothesisGenerated += ContspeechRecognizer_HypothesisGenerated;
            contspeechRecognizer.ContinuousRecognitionSession.ResultGenerated += ContinuousRecognitionSession_ResultGenerated;

            //音声が認識できない
            contspeechRecognizer.ContinuousRecognitionSession.Completed += ContinuousRecognitionSession_Completed;

            //認識開始
            await contspeechRecognizer.ContinuousRecognitionSession.StartAsync();
        }

        private static async void ContinuousRecognitionSession_Completed(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionCompletedEventArgs args)
        {
            Console.WriteLine("タイムアウトしました");
            await contspeechRecognizer.ContinuousRecognitionSession.StartAsync();
        }

        /// <summary>
        /// 認識後に画面表示
        /// </summary>
        private static void ContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
        {
            Console.WriteLine(args.Result.Text + "\n");
        }

        /// <summary>
        /// 認識中
        /// </summary>
        private static void ContspeechRecognizer_HypothesisGenerated(SpeechRecognizer sender,SpeechRecognitionHypothesisGeneratedEventArgs args)
        {
            Console.WriteLine("読み取り中 " + args.Hypothesis.Text + "\n");
        }
    }
 
}

これで実行すると、音声認識アプリが動きます。
スレッドの制御を行っていないため、精度は、かなり落ちています。
精度を上げたい人は、スレッドの制御を行ってみるといいと思います。