cscの作法 その458

# 概要
cscの作法、調べてみた。
音声認識、やってみた。

# 参考にしたページ

https://qiita.com/kob58im/items/9069dcacd3d2cb867a21

# サンプルコード

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using System.Speech.Recognition;

namespace App
{
	public static class SpeechRecognition {
		public static SpeechRecognitionEngine Engine;
		public static bool IsAvailable {
			get {
				return (Engine != null && !IsDestroyed);
			}
		}
		public static bool IsRecognizing {
			get {
				return (IsAvailable && Engine.AudioState != AudioState.Stopped);
			}
		}
		public static System.Collections.ObjectModel.ReadOnlyCollection<RecognizerInfo> InstalledRecognizers {
			get {
				return SpeechRecognitionEngine.InstalledRecognizers();
			}
		}
		public static System.Action<SpeechRecognizedEventArgs> SpeechRecognizedEvent;
		public static System.Action<RecognizeCompletedEventArgs> SpeechRecognizeCompletedEvent;
		private static bool IsDestroyed;
		static SpeechRecognition() {
			IsDestroyed = true;
		}
		public static void DestroyEngine() {
			if (!IsAvailable)
			{
				return;
			}
			Engine.SpeechRecognized -= SpeechRecognized;
			Engine.RecognizeCompleted -= SpeechRecognizeCompleted;
			Engine.UnloadAllGrammars();
			Engine.Dispose();
			IsDestroyed = true;
		}
		public static void AddGrammar(string grammarName, params string[] words) {
			Choices choices = new Choices();
			choices.Add(words);
			GrammarBuilder grammarBuilder = new GrammarBuilder();
			grammarBuilder.Append(choices);
			Grammar grammar = new Grammar(grammarBuilder) {
				Name = grammarName
			};
			if (!IsAvailable)
			{
				return;
			}
			Engine.LoadGrammar(grammar);
		}
		public static void ClearGrammar() {
			if (!IsAvailable)
			{
				return;
			}
			Engine.UnloadAllGrammars();
		}
		public static void RecognizeAsync(bool multiple) {
			if (IsRecognizing || Engine.Grammars.Count <= 0)
			{
				return;
			}
			RecognizeMode mode = (multiple) ? RecognizeMode.Multiple : RecognizeMode.Single;
			Engine.RecognizeAsync(mode);
		}
		public static void RecognizeAsyncCancel() {
			if (!IsRecognizing)
			{
				return;
			}
			Engine.RecognizeAsyncCancel();
		}
		public static void RecognizeAsyncStop() {
			if (!IsRecognizing)
			{
				return;
			}
			Engine.RecognizeAsyncStop();
		}
		public static void CreateEngine() {
			if (IsAvailable)
			{
				return;
			}
			Engine = new SpeechRecognitionEngine();
			IsDestroyed = false;
			Engine.SetInputToDefaultAudioDevice();
			Engine.SpeechRecognized += SpeechRecognized;
			Engine.RecognizeCompleted += SpeechRecognizeCompleted;
		}
		private static void SpeechRecognized(object sender, SpeechRecognizedEventArgs e) {
			if (e.Result != null && SpeechRecognizedEvent != null)
			{
				SpeechRecognizedEvent(e);
			}
		}
		private static void SpeechRecognizeCompleted(object sender, RecognizeCompletedEventArgs e) {
			if (e.Result != null && SpeechRecognizeCompletedEvent != null)
			{
				SpeechRecognizeCompletedEvent(e);
			}
		}
	}
	public class MainForm: Form {
		Dictionary<string, Action> myActions;
		public MainForm() {
			var infoCollection = SpeechRecognitionEngine.InstalledRecognizers();
			foreach (RecognizerInfo info in infoCollection)
			{
				Console.Write("desc: ");
				Console.WriteLine(info.Description);
				Console.Write("DisplayName: ");
				Console.WriteLine(info.Culture.DisplayName);
			}
			myActions = new Dictionary<string, Action>();
			myActions.Add("めもちょう", () => {
				var pInfo = new System.Diagnostics.ProcessStartInfo();
				pInfo.FileName = "notepad";
				System.Diagnostics.Process.Start(pInfo);
			});
			myActions.Add("ぺいんと", () => {
				var pInfo = new System.Diagnostics.ProcessStartInfo();
				pInfo.FileName = "mspaint";
				System.Diagnostics.Process.Start(pInfo);
			});
			myActions.Add("きゃぷちゃ", () => {
				var pInfo = new System.Diagnostics.ProcessStartInfo();
				pInfo.FileName = "snippingtool";
				System.Diagnostics.Process.Start(pInfo);
			});
			myActions.Add("テスト", () => {
			});
			SpeechRecognition.CreateEngine();
			foreach (RecognizerInfo ri in SpeechRecognition.InstalledRecognizers) 
			{
				Console.WriteLine(ri.Name + "(" + ri.Culture + ")");
			}
			SpeechRecognition.SpeechRecognizedEvent = (e) => {
				Console.WriteLine("確定：" + e.Result.Grammar.Name + " " + e.Result.Text + "(" + e.Result.Confidence + ")");
				if (myActions.ContainsKey(e.Result.Text)) 
				{
					Action act = myActions[e.Result.Text];
					act();
				}
			};
			SpeechRecognition.SpeechRecognizeCompletedEvent = (e) => {
				if (e.Cancelled) 
				{
					Console.WriteLine("キャンセルされました。");
				}
				Console.WriteLine("認識終了");
			};
			Load += (s, e) => {
				Console.WriteLine("start");
				AddGrammar();
				SpeechRecognition.RecognizeAsync(true);
			};
			Closed += (s, e) => {
				Console.WriteLine("終了");
				SpeechRecognition.RecognizeAsyncCancel();
				SpeechRecognition.RecognizeAsyncStop();
				SpeechRecognition.DestroyEngine();
			};
		}
		private void AddGrammar() {
			var tmp = myActions.Keys;
			string[] words = new string[tmp.Count];
			tmp.CopyTo(words,0);
			SpeechRecognition.AddGrammar("words", words);
		}
		[STAThread]
		static void Main(string[] args) {
			Application.Run(new MainForm());
		}
	}
}




```


# 実行結果

```
>recog2
desc: Microsoft Speech Recognizer 8.0 for Windows (Japanese - Japan)
DisplayName: 日本語 (日本)
MS-1041-80-DESK(ja-JP)
start
確定：words テスト(0.4881802)
確定：words テスト(0.340563)
確定：words めもちょう(0.2754775)
確定：words テスト(0.7999095)
確定：words ぺいんと(0.8222758)
```

以上。