音声認識アプリをC#UWPで作ってみた。[Windows.Media.SpeechRecognition]

f:id:nakadasanda1:20200514221402p:plain

windows10には、Cortanaがいます。Cortanaは、音声認識とAIと検索によって構成されているwindows10の機能の一つです。
このcortanaの音声認識の部分は、windows10のOSから提供されていおり、アプリケーションで単独で使うことができます。

cortanaとは、Microsoftによるアシスタントです。appleのsiriや、amazonのalexaのように天気を教えてくれたり、聞いた単語を検索したりするような機能が付いています。

UWPでの音声認識エンジン

この音声認識に使うためのAPIWindows.Media.SpeechRecognitionです。 このSpeechRecognizerには、2つの認識方法があります。1つ目は、単語、文法を登録して、起動、認識、終了といった1文の流れを登録するものと、
Cortanaや、siriのように、話したことをずっと聞いていてその都度予測して結果を聞くというものがあります。
今回は、Cortanaや、siriのように認識してくれるアプリを作っていきます。

UWPとは?

ユニバーサールwindowsプラットフォームのことで、windowsがversion 10になったときに、googleや、appleのように自分の会社特有のアプリストアから提供することを目標として開発が始まったアプリケーションの方法です。マイクロソフトのアプリストア↓ f:id:nakadasanda1:20200521134941p:plain

USPの特徴としては、appleandroidの開発のようにOSの機能をフル活用して、簡単にカメラの機能や、音声認識、cortanaさんに命令するなどの機能が簡単に使用できます。
従来のインストールファイルと異なり、program file等のファイルができないため安全に使うことができます。

プログラム開始

1.準備

設定からcortanaを動かす。
マイクの接続する。
Windowsアプリの開発者モードを有効可する。
Visual Studio インストーラーから「.net開発」「ユニバーサルプラットフォーム」を有効可する。
f:id:nakadasanda1:20190424133151j:plain

Visual Studioを起動します。

空白のアプリ(ユニバーサルWindows)を選択します。 f:id:nakadasanda1:20200514214004p:plain

最初にPackage.appxmanifestで機能のタブに行ってマイクにチェックを入れます。

f:id:nakadasanda1:20200527230726p:plain

次に簡単なUIを作っていきます。
ソリューションエクスプローラーからMainpage.Xamlを選択します。

f:id:nakadasanda1:20200514214749p:plain

上にGUIの画面があるページと
下にxamlソースコードがあるぺージがあります。
Xamlのページに<Grid>から下に続くページを書きます。
上の部分には、アプリケーションの保存場所だとか、アプリの名前が書かれているので、環境によって異なるなのでコピーしても無駄ですよ。

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <TextBlock x:Name="output" FontSize="24" Padding="10" Text="" Margin="0,10,0,36" TextWrapping="Wrap"></TextBlock>
        <TextBlock x:Name="textBlock1" Foreground="Aqua" TextAlignment="Center" FontSize="24" Text="Waiting..." Margin="0,968,20,0"/>
    </Grid>
</Page>

Grid内の要素は、このようになっています。,

名前 説明
TextBlock テキストを書くことのできる部分
Name オブジェクトの名前
Foreground 文字の色
FontSize フォントの大きさ
Text TextBlock中に書かれている文字となっています。

簡単なUIができたので次は、プログラムを書いていきます。 ソリューションエクスプローラーからMainpage.Xaml->Mainpage.Xaml.csを開きます。

using System;
using Windows.Media.SpeechRecognition;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// 空白ページの項目テンプレートについては、https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x411 を参照してください

namespace App1
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>

    public sealed partial class MainPage : Page
    {

        //連続音声認識のためのオブジェクト
        private SpeechRecognizer constSpeechRecognizer;
        private CoreDispatcher dispatcher;

        protected async override void OnNavigatedTo(NavigationEventArgs e)
        {

            //バックグラウンドスレッドからUIスレッドを呼び出すためのDispatcher
            dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;

             //初期化
            constSpeechRecognizer = new SpeechRecognizer();
            await constSpeechRecognizer.CompileConstraintsAsync();

            //認識の処理定義
            constSpeechRecognizer.HypothesisGenerated += ContinuousRecognitionSession_HypothesisGenerated;
            constSpeechRecognizer.ContinuousRecognitionSession.ResultGenerated += ContinuousRecognitionSession_ResultGenerated;
            constSpeechRecognizer.ContinuousRecognitionSession.Completed += ContinuousRecognitionSession_Conpleated;
            
            //処理開始
            await constSpeechRecognizer.ContinuousRecognitionSession.StartAsync();
        }

    /// <summary>
    /// 認識時間切れ
    /// </summary>

        private async void ContinuousRecognitionSession_Conpleated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionCompletedEventArgs args)
        {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                textBlock1.Text = "Timeout";
                });

            await constSpeechRecognizer.ContinuousRecognitionSession.StartAsync();
        }

    /// <summary>
    /// 認識中の文字
    /// </summary>

        private async void ContinuousRecognitionSession_HypothesisGenerated(SpeechRecognizer sender, SpeechRecognitionHypothesisGeneratedEventArgs args)
        {
                await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    textBlock1.Text = args.Hypothesis.Text;
                });
        }

    /// <summary>
    /// 認識完了後に画面に表示。
    /// </summary>
        private async void ContinuousRecognitionSession_ResultGenerated(SpeechContinuousRecognitionSession sender, SpeechContinuousRecognitionResultGeneratedEventArgs args)
        {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                textBlock1.Text = "Waiting...";
                output.Text += args.Result.Text + "。\n";
            });
        }

        public MainPage()
        {
            this.InitializeComponent();
        }

    }
}
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>

この///3つ並べたものは、visual studioが認識してくれるコメントです。
summeryの中には、Interisence(補完機能)から関数の機能を説明してくれるやつは、こうやって作られています。

実行してみるとこんな感じでマイクから音声認識をすることができます。
画面上には、ないですが、一番下に青色で現在入力途中の文字が書かれています。 f:id:nakadasanda1:20200514221402p:plain

最後に

次回は、UWPの環境からだけでなく自由にwindowsフォームや、コマンドプロンプトで実行したりできる方法について説明します。 次

nakadasanda.hatenablog.jp