次の方法で共有


連続ディクテーション

長い形式の連続ディクテーション音声入力をキャプチャして認識する方法について説明します。

重要な API: SpeechContinuousRecognitionSessionContinuousRecognitionSession

音声認識では、SpeechRecognizer オブジェクトの RecognizeAsync メソッドまたは RecognizeWithUIAsync メソッドを使用して、比較的短い音声入力をキャプチャして認識する方法を学習しました。たとえば、ショート メッセージ サービス (SMS) メッセージを作成するときや質問する場合などです。

ディクテーションや電子メールなどの長時間の継続的な音声認識セッションでは、SpeechRecognizerContinuousRecognitionSession プロパティを使用して SpeechContinuousRecognitionSession オブジェクトを取得します。

ディクテーション言語のサポートは、アプリが実行されている デバイス によって異なります。 PC とノート PC の場合、en-US のみが認識されますが、Xbox とスマートフォンでは音声認識でサポートされているすべての言語を認識できます。 詳しくは、「 音声認識エンジンの言語を指定する」をご覧ください。

セットアップ

アプリでは、継続的なディクテーション セッションを管理するためにいくつかのオブジェクトが必要です。

  • SpeechRecognizer オブジェクトのインスタンス。
  • ディクテーション中に UI を更新するための UI ディスパッチャーへの参照。
  • ユーザーが話した蓄積された単語を追跡する方法。

ここでは、 SpeechRecognizer インスタンスを分離コード クラスのプライベート フィールドとして宣言します。 1 つの拡張アプリケーション マークアップ言語 (XAML) ページを超えて継続的なディクテーションを保持する場合は、アプリで参照を他の場所に格納する必要があります。

private SpeechRecognizer speechRecognizer;

ディクテーション中、認識エンジンはバックグラウンド スレッドからイベントを発生させます。 バックグラウンド スレッドは XAML で UI を直接更新できないため、アプリはディスパッチャーを使用して認識イベントに応答して UI を更新する必要があります。

ここでは、後で UI ディスパッチャーを使用して初期化されるプライベート フィールドを宣言します。

// Speech events may originate from a thread other than the UI thread.
// Keep track of the UI thread dispatcher so that we can update the
// UI in a thread-safe manner.
private CoreDispatcher dispatcher;

ユーザーが何を言っているかを追跡するには、音声認識エンジンによって発生した認識イベントを処理する必要があります。 これらのイベントは、ユーザー発話のチャンクの認識結果を提供します。

ここでは、 StringBuilder オブジェクトを使用して、セッション中に取得されたすべての認識結果を保持します。 処理されると、新しい結果が StringBuilder に追加されます。

private StringBuilder dictatedTextBuilder;

初期化

継続的な音声認識の初期化中に、次の手順を実行する必要があります。

  • 継続的認識イベント ハンドラーでアプリの UI を更新する場合に、UI スレッドのディスパッチャーを取得します。
  • 音声認識エンジンを初期化します。
  • 組み込みのディクテーション文法をコンパイルします。 手記 音声認識では、認識可能なボキャブラリを定義するために、少なくとも 1 つの制約が必要です。 制約が指定されていない場合は、定義済みのディクテーション文法が使用されます。 音声認識を参照してください。
  • 認識イベントのイベント リスナーを設定します。

この例では、 OnNavigatedTo ページ イベントで音声認識を初期化します。

  1. 音声認識エンジンによって発生するイベントはバックグラウンド スレッドで発生するため、UI スレッドを更新するためのディスパッチャーへの参照を作成します。 OnNavigatedTo は常に UI スレッドで呼び出されます。
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. 次に、 SpeechRecognizer インスタンスを初期化します。
this.speechRecognizer = new SpeechRecognizer();
  1. 次に、 SpeechRecognizer で認識できるすべての単語と語句を定義する文法を追加してコンパイルします。

    文法を明示的に指定しない場合は、既定で定義済みのディクテーション文法が使用されます。 通常、既定の文法は一般的なディクテーションに最適です。

    ここでは、文法を追加せずにすぐに CompileConstraintsAsync を呼び出します。

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

認識イベントを処理する

RecognizeAsync または RecognizeWithUIAsync を呼び出すことで、1 つの簡単な発話またはフレーズキャプチャできます。

ただし、より長い継続的な認識セッションをキャプチャするために、ユーザーが話し、ディクテーション文字列を構築するハンドラーを定義する場合に、バックグラウンドで実行するイベント リスナーを指定します。

次に、認識エンジンの ContinuousRecognitionSession プロパティを使用して、継続的認識セッションを管理するためのメソッドとイベントを提供する SpeechContinuousRecognitionSession オブジェクトを取得します。

特に、次の 2 つのイベントが重要です。

  • ResultGenerated。認識エンジンが何らかの結果を生成したときに発生します。
  • 完了。これは、継続的な認識セッションが終了したときに発生します。

ResultGenerated イベントは、ユーザーが話すと発生します。 認識エンジンはユーザーを継続的に監視し、音声入力の断片を渡すイベントを定期的に発生させます。 イベント引数の Result プロパティを使用して音声入力を調べ、StringBuilder オブジェクトにテキストを追加するなど、イベント ハンドラーで適切なアクションを実行する必要があります。

SpeechRecognitionResult のインスタンスとして、Result プロパティは、音声入力を受け入れるかどうかを判断するのに役立ちます。 SpeechRecognitionResult には、次の 2 つのプロパティがあります。

  • 状態 は、認識が成功したかどうかを示します。 認識は、さまざまな理由で失敗する可能性があります。
  • 信頼度 は、認識エンジンが正しい単語を理解した相対的な信頼度を示します。

継続的認識をサポートするための基本的な手順を次に示します。

  1. ここでは、OnNavigatedTo ページ イベントの ResultGenerated 継続的認識イベントのハンドラーを登録します。
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. 次に、 Confidence プロパティを確認します。 信頼度の値が 以上の場合は、文字列Builder にテキストを追加します。 また、入力を収集するにつれて UI も更新されます。

    ResultGenerated イベントは、UI を直接更新できないバックグラウンド スレッドで発生します。 ハンドラーが UI を更新する必要がある場合 ([Speech と TTS のサンプル] のように)、ディスパッチャーの RunAsync メソッドを使用して UI スレッドに更新をディスパッチする必要があります。

private async void ContinuousRecognitionSession_ResultGenerated(
      SpeechContinuousRecognitionSession sender,
      SpeechContinuousRecognitionResultGeneratedEventArgs args)
      {

        if (args.Result.Confidence == SpeechRecognitionConfidence.Medium ||
          args.Result.Confidence == SpeechRecognitionConfidence.High)
          {
            dictatedTextBuilder.Append(args.Result.Text + " ");

            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              dictationTextBox.Text = dictatedTextBuilder.ToString();
              btnClearText.IsEnabled = true;
            });
          }
        else
        {
          await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              dictationTextBox.Text = dictatedTextBuilder.ToString();
            });
        }
      }
  1. 次に、継続的なディクテーションの終了を示す Completed イベントを処理します。

    セッションは、StopAsync メソッドまたは CancelAsync メソッドを呼び出すと終了します (次のセクションで説明します)。 セッションは、エラーが発生したとき、またはユーザーが話を停止したときに終了することもできます。 セッションが終了した理由を判断するには、イベント引数の Status プロパティを確認します (SpeechRecognitionResultStatus)。

    ここでは、OnNavigatedTo ページ イベントの Completed 継続的認識イベントのハンドラーを登録します。

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. イベント ハンドラーは Status プロパティを調べて、認識が成功したかどうかを判断します。 また、ユーザーが話を停止した場合も処理されます。 多くの場合、 TimeoutExceeded は、ユーザーが話し終わったため、正常な認識と見なされます。 適切なエクスペリエンスを得るためのコードでは、このケースを処理する必要があります。

    ResultGenerated イベントは、UI を直接更新できないバックグラウンド スレッドで発生します。 ハンドラーが UI を更新する必要がある場合 ([Speech と TTS のサンプル] のように)、ディスパッチャーの RunAsync メソッドを使用して UI スレッドに更新をディスパッチする必要があります。

private async void ContinuousRecognitionSession_Completed(
      SpeechContinuousRecognitionSession sender,
      SpeechContinuousRecognitionCompletedEventArgs args)
      {
        if (args.Status != SpeechRecognitionResultStatus.Success)
        {
          if (args.Status == SpeechRecognitionResultStatus.TimeoutExceeded)
          {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              rootPage.NotifyUser(
                "Automatic Time Out of Dictation",
                NotifyType.StatusMessage);

              DictationButtonText.Text = " Continuous Recognition";
              dictationTextBox.Text = dictatedTextBuilder.ToString();
            });
          }
          else
          {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              rootPage.NotifyUser(
                "Continuous Recognition Completed: " + args.Status.ToString(),
                NotifyType.StatusMessage);

              DictationButtonText.Text = " Continuous Recognition";
            });
          }
        }
      }

継続的な認識フィードバックを提供する

人々が会話するとき、彼らは多くの場合、言われていることを完全に理解するためにコンテキストに依存します。 同様に、音声認識エンジンには、多くの場合、信頼度の高い認識結果を提供するためのコンテキストが必要です。 たとえば、それ自体では、"weight" と "wait" という単語は、周囲の単語からより多くのコンテキストを収集できるようになるまで区別できません。 認識エンジンは、単語 (単語) が正しく認識されたことをある程度確信するまで、 ResultGenerated イベントを発生させません。

これにより、ユーザーが話し続ける際に理想的なエクスペリエンスが得られなくなり、認識エンジンが ResultGenerated イベントを発生させるのに十分な信頼度が得られるまで、結果は提供されません。

この明らかな応答性の欠如を改善するために 、HypothesisGenerated イベントを処理します。 このイベントは、処理対象の単語に一致する可能性のある新しいセットが認識エンジンによって生成されるたびに発生します。 イベント引数は、現在の一致を含む 仮説 プロパティを提供します。 話し続けるユーザーにこれらを表示し、処理がまだ進行中であることを伝え、安心させます。 信頼度が高く、認識結果が決定されたら、中間仮説の結果を ResultGenerated イベントで提供される最終的な結果に置き換えます。

ここでは、仮定のテキストと省略記号 ("...") を出力 TextBox の現在の値に追加します。 新しい仮説が生成され、 ResultGenerated イベントから最終的な結果が取得されるまで、テキスト ボックスの内容が更新されます。

private async void SpeechRecognizer_HypothesisGenerated(
  SpeechRecognizer sender,
  SpeechRecognitionHypothesisGeneratedEventArgs args)
  {

    string hypothesis = args.Hypothesis.Text;
    string textboxContent = dictatedTextBuilder.ToString() + " " + hypothesis + " ...";

    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
      dictationTextBox.Text = textboxContent;
      btnClearText.IsEnabled = true;
    });
  }

認識の開始と停止

認識セッションを開始する前に、音声認識エンジンの State プロパティの値を確認します。 音声認識エンジンは アイドル 状態である必要があります。

音声認識エンジンの状態を確認した後、音声認識エンジンの ContinuousRecognitionSession プロパティの StartAsync メソッドを呼び出してセッションを開始します。

if (speechRecognizer.State == SpeechRecognizerState.Idle)
{
  await speechRecognizer.ContinuousRecognitionSession.StartAsync();
}

認識は、次の 2 つの方法で停止できます。

  • StopAsync を使用すると、保留中の認識イベントを完了できます (ResultGenerated は、保留中のすべての認識操作が完了するまで引き続き発生します)。
  • CancelAsync は認識セッションを直ちに終了し、保留中の結果をすべて破棄します。

音声認識エンジンの状態を確認した後、音声認識エンジンの ContinuousRecognitionSession プロパティの CancelAsync メソッドを呼び出してセッションを停止します。

if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
  await speechRecognizer.ContinuousRecognitionSession.CancelAsync();
}

ResultGenerated イベントは、CancelAsync の呼び出し後に発生する可能性があります。
マルチスレッドのため、CancelAsync が呼び出されたときに ResultGenerated イベントがスタックに残る可能性があります。 その場合、この ResultGenerated イベントは引き続き発生します。
認識セッションをキャンセルするときにプライベート フィールドを設定する場合は、 常に ResultGenerated ハンドラーでその値を確認します。 たとえば、セッションを取り消すときにフィールドを null に設定した場合は、ハンドラーでフィールドが初期化されていると想定しないでください。

 

  • 音声での対話

サンプル