HeyCHのブログ

慢性疲労のへいちゃんです

【C#】音声認識して、文字列にしてみよう

今回の記事では、マイクで拾った音声を認識して、文字列にしてみようという事でやっていきたいと思います。
音声認識エンジンはいろいろあるようなのですが、Windows標準で使える「System.Speech」を使用してみたいと思います。

音声認識は、「3分タイマーを起動して」みたいな感じで、「3分」「タイマー」「起動」という事を認識してアプリケーションを実行するタイプもあるのですが、辞書みたいなのを作るのが面倒であるため、今回は、マイクで拾った音を文字列に起こすというのを目標にやっていきたいと思います。

プロジェクトの準備

「参照」>右クリック「参照の追加」で「System.Speech」を追加します。
f:id:HeyCH:20200509004632p:plain

XAML

<Window x:Class="VoiceRecognition.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:VoiceRecognition"
        mc:Ignorable="d"
        Title="音声認識アプリ" Height="320" Width="440">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="25"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding Text}" Grid.Row="0"/>
        <TextBox Text="{Binding Voice}" Grid.Row="1"/>
    </Grid>
</Window>

コード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Speech.Recognition;

namespace VoiceRecognition {
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window {
        ViewModel vm;
        SpeechRecognitionEngine engine;
        public MainWindow() {
            InitializeComponent();
            vm = new ViewModel();
            this.DataContext = vm;
            engine = new SpeechRecognitionEngine();
            engine.SpeechRecognized += Engine_SpeechRecognized;//認識処理
            engine.SpeechHypothesized += Engine_SpeechHypothesized;//推定処理
            engine.LoadGrammar(new DictationGrammar());//ディクテーション用の辞書
            engine.SetInputToDefaultAudioDevice();//エンジンの入力
            engine.RecognizeAsync(RecognizeMode.Multiple);//開始
        }

        private void Engine_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e) {
            vm.Voice = e.Result.Text;
        }

        private void Engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) {
            vm.Voice = e.Result.Text;
            vm.Text = e.Result.Text;
        }
    }
    public class ViewModel : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        string _Text = "";
        public string Text {
            get {
                return _Text;
            }
            set {
                _Text = value + "\r\n" + Text;
                OnPropertyChanged("Text");
            }
        }
        string _Voice = "";
        public string Voice {
            get {
                return _Voice;
            }
            set {
                _Voice = value;
                OnPropertyChanged("Voice");
            }
        }
    }
}
  • はきはきしゃべると認識率が高くなるようです。

f:id:HeyCH:20200509004648p:plain