System.Speech でディクテーション(音声を文字列)にする

マイクのイメージ。

ディクテーションとは音声認識結果をテキスト・文字列にする処理です。 昨今の Windows(.NET) には標準的に System.Speech ライブラリが用意されているので、 これを C# * VisualStudio * .NETFramework から参照し、音声認識するサンプルを紹介します。

サンプルプログラム

ディクテーションのサンプルプログラムのスクリーンショット。

サンプルプログラムのスクリーンショットです。多少雑音が入ったりしているため、変な文字が入力されていますが、まぁ良いでしょう。 白い丸が推定状態、黒い丸が認識状態です。推定・認識状態については後に続くコンテンツを参照してください。

VisualStudio 2013 Community, C#, .NETFrameowrk4.x, WPF で作られています。 Dictation_SSpeech.zip

音声認識エンジンの用意

ここでは Visual Studio を使った実装のサンプルとして紹介しています。 参照設定から「アセンブリ > フレームワーク > System.Speech」を追加します。

音声認識処理をするためには概ね次の手順が必要です。

  1. 音声認識エンジンを用意する
  2. 音声認識エンジンに認識させる語句を追加する
  3. 音声認識エンジンに入力する音声ストリームを指定する
  4. 音声認識エンジンが認識処理を実行したときの処理を設定する
  5. 音声認識処理を開始する

これらは次のようなコードで実現されます。 ここで認識させる語句(の辞書)とは、ディクテーション処理専用の語句(の辞書)になります。

一般的な音声認識は特定の語句が発せられたかどうかを識別するレコグニションの処理を行います。 そこで、特定の語句がセットになった辞書を登録します。 ディクテーションの場合は、(識別可能な)あらゆる語句を識別する必要があるため、 ユーザが任意に指定する語句ではなく、ディクテーション用のものを使います。

おそらく語句を無数に登録した自作の辞書でも同じようなことができますが、実装がしんどいと思います。

using System.Speech.Recognition;

SpeechRecognitionEngine recogEngine;

recogEngine = new SpeechRecognitionEngine();

// 音声認識が認識処理を終えたときのイベントハンドラを設定する。
recogEngine.SpeechRecognized += recogEngine_SpeechRecognized;

// 音声認識が推定処理を終えたときのイベントハンドラを設定する。
recogEngine.SpeechHypothesized += recogEngine_SpeechHypothesized;

// SystemSpeech を利用したディクテーションを行う場合には、
// DictationGrammar (ディクテーション用の辞書) を追加する。
recogEngine.LoadGrammar(new DictationGrammar());

// 実行環境の標準の入力を音声認識エンジンの入力とする。
recogEngine.SetInputToDefaultAudioDevice();

// 非同期の認識を継続して実行するようにして音声認識を開始する。
recogEngine.RecognizeAsync(RecognizeMode.Multiple);

イベントハンドラを使って認識時の処理を実装します。他の方法については割愛します。 System.Speech による音声認識処理は、「入力 > 推定 > 否定 or 肯定」のように進みます。 推定時の処理、肯定(認識)時の処理といったように場合分けすることができます。

ここでは次のようなコードによって、単純にテキストボックスに出力します。

// 推定時の処理
void recogEngine_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
{
    this.textBox.Text = "○" + e.Result.Text + "("+ e.Result.Confidence + ")\n" + this.textBox.Text;
}

// 認識時の処理
void recogEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    this.textBox.Text = "●" + e.Result.Text + "(" + e.Result.Confidence + ")\n" + this.textBox.Text;
}

protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);

    // 終了時には破棄する。
    recogEngine.Dispose();
}