hyoromoのブログ

iOS/AndroidもしくはCocos2dxネタを書いています

アプリ上で音声認識検索を行う


Windows Phone 8から音声認識検索が可能になりました。どこからでもスタートボタンを長押しする事で、音声認識検索で端末上のアプリを起動する事が出来ます。

音声認識検索はシステム上だけではなく、アプリ上からも利用可能です。今回はアプリ上から音声認識検索を行う方法を書きます。

利用APIについて

利用するのはSpeechRecognizerになります。使い方としては、音声検索画面のUIを使用するパターンと、使用しないパターンがあります。使用する場合は音声認識前に「お話しください」と表示され、音声認識後に「○○を起動します」とMessageBoxが表示されます。使用しない場合はUIは何も表示されずに音声認識を開始する為、アプリ開発者側が開始と終了を画面上に示す必要があります。

このAPIを利用する上で、事前に以下の3つの機能を利用する宣言を行う必要があります。宣言箇所は「Properties/WMAppManifest.xml」の機能タブです。

  • ID_CAP_SPEECH_RECOGNITION
  • ID_CAP_MICROPHONE
  • ID_CAP_NETWORKING

音声認識検索の画面を表示するパターン


UIを表示するパターンは以下のようになります。コードを実行する事で、上記のように表示されます(左:検索前、真ん中:検索後、右:検索失敗)。

public partial class MainPage : PhoneApplicationPage {
    SpeechRecognizerUI speechRecognizerUi;

    public MainPage() {
        InitializeComponent();

        speechRecognizerUi = new SpeechRecognizerUI();
        speechRecognizerUi.Recognizer.Grammars.AddGrammarFromList("animal", new List<string>() { "いぬ", "さる", "ねこ" }); // 音声認識の候補
        speechRecognizerUi.Settings.ListenText = "好きな動物は以下のうちどれ?";  // 音声検索画面上のタイトル
        speechRecognizerUi.Settings.ExampleText = "・いぬ\n・さる\n・ねこ";  // 音声検索画面上の詳細
        // speechRecognizerUi.Settings.ReadoutEnabled = false; // 結果の読み上げを行うか
        // speechRecognizerUi.Settings.ShowConfirmation = false; // 結果の確認を行う画面を表示するか
    }

    // トリガーとしてのボタンが押下された時の処理
    private async void btnSearch_Click(object sender, RoutedEventArgs e) {
        try {
            SpeechRecognitionUIResult result = await speechRecognizerUi.RecognizeWithUIAsync();
            if (result.ResultStatus == SpeechRecognitionUIStatus.Succeeded) {
                // 音声認識の結果が得られた時の処理
                // MessageBox.Show(result.RecognitionResult.Text);
            } else {
                // 音声認識をキャンセルした時の処理
            }
        } catch (Exception err) {
            // 例外処理
        }
    }
}

UIを表示させる場合に利用するAPISpeechRecognizerUIとなります。音声認識APIの要であるSpeechRecognizer Classは、SpeechRecognizerUI.Recognizerにて取得可能です。
音声認識検索の対象候補をSpeechRecognizerUI.Recognizer.Grammarsに設定する事になり、List(コレクション)uri(XML)PredefinedType(使ってみたが何か分からなかった)があります。上記コードではコレクションで定義しています。

検索前のMessageBox表示メッセージを変更

UI上に表示する文言はSpeechRecognizerUI.Settingsで設定する事になります。音声検索前に表示されるMessageBox上のタイトルと詳細メッセージが設定可能です。

非同期で行う事に注意

音声認識は非同期で行われる為、音声認識を開始するSpeechRecognizerUI.RecognizeWithUIAsyncメソッドの先頭にawaitを付け、このAPIを実行するメソッドにasync修飾子を追加します。結果はSpeechRecognitionUIResultで返ってくる為、結果のステータス判断を行った上でSpeechRecognitionUIResult.RecognitionResult.Textプロパティで値を取得してください。

細かい設定

結果に表示されるタイトル「次のアプリですね・・・」が固定表示され、詳細「いぬ」は音声認識結果が表示されます。結果の文言は変更不可な為、結果画面が気に入らなければSpeechRecognizerUI.i.Settings.ShowConfirmationにfalseを設定して自分で表示してください。
音声認識後の画面では音声が読み上げられます。嫌な場合はSpeechRecognizerUI.i.Settings.ReadoutEnabledにfalseを設定してください。

音声認識検索の画面を表示しないパターン

UIを表示しないパターンは以下のようになります。

public partial class MainPage : PhoneApplicationPage
{
    SpeechRecognizer speechRecognizer;
    IAsyncOperation<SpeechRecognitionResult> operation;

    public MainPage() {
        InitializeComponent();

        speechRecognizer = new SpeechRecognizer();
        speechRecognizer.Grammars.AddGrammarFromList("animal", new List<string>() { "いぬ", "さる", "ねこ" }); // 音声認識の候補
    }

    // トリガーとしてのボタンが押下された時の処理
    private async void btnSearch_Click(object sender, RoutedEventArgs e) {
        try {
            operation = speechRecognizer.RecognizeAsync();
            SpeechRecognitionResult result = await operation;
            if (result.TextConfidence != SpeechRecognitionConfidence.Rejected) {
                // 音声認識の結果が得られた時の処理
                // MessageBox.Show(result.Text);
            } else {
                // 認識候補とマッチしなかった場合の処理
            }
        } catch (Exception err) {
            // 例外処理
        }
    }
}

UI表示しない場合、音声認識中であるか分からず、認識候補にマッチする文言が無い場合に再度音声認識をユーザへ要求する処理もありません。その2点以外はUI画面を表示するコードと実装方法に差はないです。