Microsoft Speech SDK で音声認識

VC6/音声認識プログラムを作る前に

最終更新: 2015-04-02 (木) 10:32:57 (2007d)

概要

このページでは、以下のコンパイラでMSSDKを使った開発を行う際の基本的な設定に関して説明する。

想定する開発環境

  • Microsoft Visual C++ 6.0 Service Pack 5

Microsoft Speech SDK のインストール

まだ MSSDK をインストールしていない場合は、Microsoft Speech SDKによる日本語音声認識の設定 の編集を参照すること。

VC++ の設定

MSSDK のインストールディレクトリには、include・lib\i386 というディレクトリが存在する。 「ツール」⇒「オプション」⇒「ディレクトリ」の インクルードディレクトリ・ライブラリディレクトリにそれぞれこれらのディレクトリを追加しよう。

Microsoft Speech SDKによる音声認識プログラムの概要

MSSDK を使って音声認識を行うには、 主に ISpRecoRecognizer、ISpRecoContext、ISpRecoGrammar の3つのインターフェイスを用いる。 それぞれの役割を以下に示す。

  • ISpRecoRecognizer インターフェイス

音声認識を扱うインターフェイス、音声認識はすべてここから始まる。

  • ISpRecoContext インターフェイス

音声認識の文脈を扱うインターフェイス、状況に応じて文脈を使い分けることを可能にする。

  • ISpRecoGrammar インターフェイス

音声認識の文法を扱うインターフェイス、文法を設定することで音声認識の出力方式を指定できる。

さらにヘルパークラスとして、 外部デバイス(デフォルトではマイク)から音声を取り込むための ISpAudio インターフェイスがある。

本ページでは、これらのインターフェイスの初期化コードをカプセル化した Dictator クラスを作成し、使用している。

Dictator クラスについて

本ページで扱う全てのサンプルでは、音声認識の中核として独自に定義した Dictator クラスを使う。 このクラスは、音声認識を行うために MSSDK から提供されているインターフェイス群の初期化コードなどをカプセル化する。 音声認識に使用するインターフェイスが相互にどのような関係にあり、 また Dictator クラスとどのような関係にあるのかを表すオブジェクト図を以下に示す。

object.png

grammar は context によって生成され、context は recognizer によって生成される。 従って、プログラムは recognizer → context → grammar という順番でオブジェクトを生成する。 Dictator クラスの initialize メソッドの定義として、fileDictator.cpp の一部を以下に示す。

bool Dictator::initialize(const ULONGLONG guid) {
  // 音声認識エンジンのインスタンスを構築する
  if(FAILED(lastResult_=recognizer_.CoCreateInstance(CLSID_SpInprocRecognizer))) {
    return false;
  }

  // 認識コンテキストを構築する
  if(FAILED(lastResult_=recognizer_->CreateRecoContext(&context_))) {
    return false;
  }

  // ...

  // 文法を構築する
  if(FAILED(lastResult_=context_->CreateGrammar(guid, &grammar_))) {
    return false;
  }

  // ...

  return true;
}

recognizer は、音声を入力するためのストリームを設定することで、 そのストリームから流れてくる音声を認識する。 今回は、音声入力として ISpAudio によるマイク音声入力を用いた。

そして、最も重要なところであるが recognizer によって認識された結果が、 context によって Dictator クラスに通知されるようにプログラムを製作する。 Dictator クラスの定義として、fileDictator.hpp の一部を以下に示す。

class Dictator : public ISpNotifyCallback {
  // ...

public:
  /// 認識コンテキストのイベントを受信します。
  HRESULT STDMETHODCALLTYPE NotifyCallback(WPARAM wParam, LPARAM lParam);
};

ISpRecoContext からイベントを受け取る方法はいくつかあるが、 そのうちの一つとして ISpNotifyCallback インターフェイスを用いる方法があり、今回はそれを利用する。 ISpNotifyCallback インターフェイスは、NotifyCallback メソッドのみを持ち、Dictator クラスはそれを実装する。 また、ISpRecoContext から Dictator へ通知がくるように設定している Dictator クラスの initialize メソッドの定義として、 fileDictator.cpp の一部を以下に示す。

bool Dictator::initialize(const ULONGLONG guid) {
  // ...

  // 通知の受信を設定する
  if(FAILED(lastResult_=context_->SetNotifyCallbackInterface(this, 0, 0))) {
    return false;
  }

  // ...

  return true;
}

以上のようにプログラムすることで、音声認識イベントが発生したときに Dictator::NotifyCallback メソッドが呼び出されるようになる。 音声認識のイベントは各種存在するが、 本プログラムでは、音声認識結果報告・音声入力開始・音声入力終了の3つのイベントのみを取り扱う。 以上の3種類のイベントを Dictator が受け取った場合、Dictator はイベントの種類によって それぞれ recognized, soundStarted, soundStop メソッドを呼び出す。 これらは仮想メソッドであり、音声認識を処理するプログラムを書く場合は、 これらのメソッドを適切にオーバーライドする。 イベントを振り分ける処理をしている Dictator クラスの NotifyCallback メソッドの定義として、 fileDictator.cpp の一部を以下に示す。

HRESULT STDMETHODCALLTYPE Dictator::NotifyCallback(WPARAM wParam, LPARAM lParam) {
  CSpEvent event;
  while(event.GetFrom(context_)==S_OK) {
    switch(event.eEventId) {
    case SPEI_RECOGNITION:
      recognized(event);
      break;
    case SPEI_SOUND_START:
      soundStarted(event);
      break;
    case SPEI_SOUND_END:
      soundStoped(event);
      break;
    }
  }  // while

  return S_OK;
}

最後に文法に関して、MSSDK では状況に応じた文法を読み込み、音声認識の精度を上げることができる。 文法の設定は、どのような状況下で音声認識を行うかの重要な設定であり、 Dictator クラスはこれを使い分けることができるように initializeGrammar 仮想メソッドを持つ。 このメソッドは、Dictator::initialize メソッドで呼び出されるメソッドで、 ISpRecoGrammar インスタンスを一つ受け取る。 文法を設定するためには、このメソッドを適切にオーバーロードする。 Dictator クラスの定義として、fileDictator.hpp の一部を以下に示す。

class Dictator : public ISpNotifyCallback {
protected:
  /// 文法を初期化します。
  virtual HRESULT initializeGrammar(const CComPtr<ISpRecoGrammar>& grammar)=0;
};

Dictator クラスを使った音声認識プログラムの開発

Dictator クラスは、 音声認識を行うために MSSDK から提供されているインターフェイス群の初期化コード およびイベント受信をカプセル化しており、適切なタイミングで Dictator クラスの soundStarted, soundStoped, recognized, initializeGrammar メソッドが呼び出される。 従って、Dictator クラスを使った音声認識プログラムの開発は、 Dictator クラスを継承した独自のクラスを作成し、 soundStarted, soundStoped, recognized, initializeGrammar メソッドをオーバーライドすることである。 例として、Dictator クラスを継承した標準クラス StandardDictator の定義を以下に示す。

class StandardDictator : public Dictator {
public:
  HRESULT initializeGrammar(const CComPtr<ISpRecoGrammar>& grammar);

public:
  HRESULT recognized(CSpEvent& event);
  HRESULT soundStarted(CSpEvent& event);
  HRESULT soundStoped (CSpEvent& event);
};

コメント

コメントはありません。 コメント/mssdk/vc6/prepare

お名前: