Microsoft Speech SDK で音声認識

VC6/指定文法音声認識の結果からプロパティ情報を取得する

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

概要

指定文法による音声認識を行うには、VC6/指定文法を扱う音声認識を事前に参照のこと。

このページで説明するコード。

プロパティについて

指定文法による音声認識では、文法の任意の部分にプロパティという情報を付加することができる。 XML による文法指定では、 PROPNAME, VAL, VALSTR という3つの属性によってプロパティ情報を扱う。 以下にプロパティ情報を付加した文法の例を示す。

<P PROPNAME="human" VAL="1">豊</P>

<P PROPNAME="human" VALSTR="著者">豊</P>

<P PROPNAME="human" VAL="1" VALSTR="著者">豊</P>

<L PROPNAME="human">
	<P VAL="1">豊</P>
	<P VAL="2">弥</P>
</L>

PROPNAME は、プロパティ名を指定する属性である。 それに対して VAL, VALSTR はプロパティの具体的な値を指定する属性である。 VALには整数値を、VALSTR には文字列を指定できる。 PROPNAME と VAL・VALSTR はペアでひとつの情報となる。 一つのプロパティに対して VAL と VALSTR の二つの情報を付加しても特に問題はない。

指定文法による音声認識を行いプロパティ情報が付加されたフレーズが認識されると、 認識結果としてそのプロパティ情報が取得できるようになる。 このプロパティ情報を利用することで、 認識結果テキストを解析することなく文法のどの部分を認識したかを判断することができる。

文法の任意の部分にプロパティ情報を指定できるので、 一回の音声認識によって得られるプロパティ情報は一般的に複数である。 それらの情報は、認識した順番によって並べられたリストとして取得できる。 一回の音声認識によって得られるプロパティ情報には、同名のプロパティがあっても構わない。 それらは認識した順番によって並べられる。

PhraseProperty クラスを導入する

SAPI では、SPPHRASEPROPERTY という構造体によってプロパティ情報が表現されている。 この構造体は pNextSibling メンバによって連なるリストである。 一つの SPPHRASEPROPERTY は、一つのプロパティを表す。以下に、重要なメンバとその役割を示す。

メンバ役割
pszNameWCHAR*プロパティ名
vValueVARIANTVALの値
pszValueWCHAR*VALSTRの値

このままだと扱いにくいので、 WCHAR を std::string に VARIANT を long に変換する PhraseProperty クラスを定義する。 以下に PhraseProperty クラスのコンストラクタとして、filePhraseProperty.cpp の一部を示す。

PhraseProperty::PhraseProperty(const SPPHRASEPROPERTY* property) :
name_(WChar2Char(property->pszName)) {
  // VALの値を取得する
  switch(V_VT(&property->vValue)) {
  case VT_I4:
    hasVal_=true;
    val_=V_I4 (&property->vValue);
    break;
  case VT_UI4:
    hasVal_=true;
    val_=V_UI4(&property->vValue);
    break;
  default:
    hasVal_=false;
    break;
  }

  // VALSTRの値を取得する
  if(hasValStr_=(0!=property->pszValue)) {
    valstr_=WChar2Char(property->pszValue);
  }
}

WChar2Char は、ワイドキャラクタ(WCHAR)を普通のキャラクタ(char)に変換するために定義したクラスで 補足で補足説明する。 VARIANT 型は、任意のデータ型を返すデータ構造で switch 文によって内容の種類ごとに処理を振り分けている。 今回は VT_I4(LONG)、VT_UI4(ULONG) の二つの型のみをサポートしている *1

プロパティ情報を出力する

認識した結果のプロパティ情報を出力するように、 CmdFileDictator クラスの recognized メソッドを実装する。 認識結果のすべてのプロパティ情報を出力するために、 gNextSibling メンバによって連なるすべての SPPHRASEPROPERTY を出力する。 以下に CmdFileDictator クラスの一部として、fileCmdFileDictator.cpp の一部を示す。

HRESULT CmdFileDictator::recognized(CSpEvent& event) {
  /// ...

  // フレーズを取得する
  SPPHRASE* phrase;
  if(FAILED(result=event.RecoResult()->GetPhrase(&phrase))) {
    return result;
  }

  // フレーズからプロパティ情報を取得する
  for(const SPPHRASEPROPERTY* p=phrase->pProperties;p!=0;p=p->pNextSibling) {
    PhraseProperty property(p);

    cout << property.getName() << " :";
    if(property.hasVal()) {
      cout << " VAL =" << property.getVal();
    }
    if(property.hasValStr()) {
      cout << " VALSTR =" << property.getValStr();
    }
    cout << endl;
  }

  /// ...
}

補足

ワイドキャラクタからキャラクタへの変換を行う関数として Windows では、 WideCharToMultiByte 関数が用意されている。 また、その逆の変換としてキャラクタからワイドキャラクタへの変換を行う関数として、 MultiByteToWideChar 関数が用意されている。 以上の変換を任意の長さの文字列を対象として行うためには、 変換結果を受け取るためのメモリ領域を動的に確保しなければならない。 WChar2Char と Char2WChar の二つのクラスは、そのメモリ領域の確保および破棄と、 実際の変換を行う隠蔽する。

この二つのクラスは、char* やwchar* へのキャスト演算子を定義していることから、 関数のように使用することができる。 以下に、ワイドキャラクタを std::string に変換する記述を示す。

WCHAR* buffer;

// ...

std::string translated(WChar2Char(buffer));

コメント

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

お名前: