연속 받아쓰기Continuous dictation

Long 형식의 연속 받아쓰기 음성 입력을 캡처하고 인식 하는 방법에 대해 알아봅니다.Learn how to capture and recognize long-form, continuous dictation speech input.

중요 한 api: SpeechContinuousRecognitionSession, ContinuousRecognitionSessionImportant APIs: SpeechContinuousRecognitionSession, ContinuousRecognitionSession

음성 인식에서 SpeechRecognizer 개체의 RecognizeAsync 또는 RecognizeWithUIAsync 메서드 (예: SMS (short message service) 메시지를 작성 하거나 질문을 할 때)를 사용 하 여 비교적 짧은 음성 입력을 캡처하고 인식 하는 방법을 배웠습니다.In Speech recognition, you learned how to capture and recognize relatively short speech input using the RecognizeAsync or RecognizeWithUIAsync methods of a SpeechRecognizer object, for example, when composing a short message service (SMS) message or when asking a question.

더 긴 경우 받아쓰기 또는 전자 메일과 같은 연속 음성 인식 세션에서는 SpeechRecognizerContinuousRecognitionSession 속성을 사용 하 여 SpeechContinuousRecognitionSession 개체를 가져옵니다.For longer, continuous speech recognition sessions, such as dictation or email, use the ContinuousRecognitionSession property of a SpeechRecognizer to obtain a SpeechContinuousRecognitionSession object.

참고

받아쓰기 언어 지원은 앱이 실행 되는 장치 에 따라 다릅니다.Dictation language support depends on the device where your app is running. Pc와 노트북의 경우 en-us만 인식 되 고 Xbox 및 휴대폰은 음성 인식에서 지원 되는 모든 언어를 인식할 수 있습니다.For PCs and laptops, only en-US is recognized, while Xbox and phones can recognize all languages supported by speech recognition. 자세한 내용은 음성 인식기 언어 지정을 참조 하세요.For more info, see Specify the speech recognizer language.

설정Set up

연속 받아쓰기 세션을 관리 하려면 앱에 몇 개의 개체가 필요 합니다.Your app needs a few objects to manage a continuous dictation session:

  • SpeechRecognizer 개체의 인스턴스입니다.An instance of a SpeechRecognizer object.
  • 받아쓰기 중 UI를 업데이트 하기 위한 UI 디스패처에 대 한 참조입니다.A reference to a UI dispatcher to update the UI during dictation.
  • 사용자가 말한 누적 단어를 추적 하는 방법입니다.A way to track the accumulated words spoken by the user.

여기에서는 SpeechRecognizer 인스턴스를 코드 숨김이 클래스의 전용 필드로 선언 합니다.Here, we declare a SpeechRecognizer instance as a private field of the code-behind class. 연속 받아쓰기를 단일 Extensible Application Markup Language (XAML) 페이지 이상으로 유지 하려면 앱은 다른 곳에 참조를 저장 해야 합니다.Your app needs to store a reference elsewhere if you want continuous dictation to persist beyond a single Extensible Application Markup Language (XAML) page.

private SpeechRecognizer speechRecognizer;

받아쓰기를 수행 하는 동안 인식기는 백그라운드 스레드에서 이벤트를 발생 시킵니다.During dictation, the recognizer raises events from a background thread. 백그라운드 스레드는 XAML에서 UI를 직접 업데이트할 수 없으므로 앱에서 디스패처를 사용 하 여 인식 이벤트에 대 한 응답으로 UI를 업데이트 해야 합니다.Because a background thread cannot directly update the UI in XAML, your app must use a dispatcher to update the UI in response to recognition events.

여기서는 나중에 UI 디스패처를 사용 하 여 초기화 되는 전용 필드를 선언 합니다.Here, we declare a private field that will be initialized later with the UI dispatcher.

// 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;

사용자의 의견을 추적 하려면 음성 인식기에서 발생 하는 인식 이벤트를 처리 해야 합니다.To track what the user is saying, you need to handle recognition events raised by the speech recognizer. 이러한 이벤트는 사용자 길이 발언의 청크에 대 한 인식 결과를 제공 합니다.These events provide the recognition results for chunks of user utterances.

여기서는 StringBuilder 개체를 사용 하 여 세션 중에 얻은 모든 인식 결과를 저장 합니다.Here, we use a StringBuilder object to hold all the recognition results obtained during the session. 새 결과는 처리 될 때 StringBuilder 에 추가 됩니다.New results are appended to the StringBuilder as they are processed.

private StringBuilder dictatedTextBuilder;

초기화Initialization

연속 음성 인식을 초기화 하는 동안 다음을 수행 해야 합니다.During the initialization of continuous speech recognition, you must:

  • 연속 인식 이벤트 처리기에서 응용 프로그램의 UI를 업데이트 하는 경우 UI 스레드에 대 한 디스패처를 인출 합니다.Fetch the dispatcher for the UI thread if you update the UI of your app in the continuous recognition event handlers.
  • 음성 인식기를 초기화 합니다.Initialize the speech recognizer.
  • 기본 제공 받아쓰기 문법을 컴파일합니다.Compile the built-in dictation grammar. 참고    음성 인식은 인식할 수 있는 어휘를 정의 하는 하나 이상의 제약 조건이 필요 합니다.Note   Speech recognition requires at least one constraint to define a recognizable vocabulary. 제약 조건을 지정 하지 않으면 미리 정의 된 받아쓰기 문법이 사용 됩니다.If no constraint is specified, a predefined dictation grammar is used. 음성 인식을 참조 하세요.See Speech recognition.
  • 인식 이벤트에 대 한 이벤트 수신기를 설정 합니다.Set up the event listeners for recognition events.

이 예제에서는 OnNavigatedTo page 이벤트에서 음성 인식을 초기화 합니다.In this example, we initialize speech recognition in the OnNavigatedTo page event.

  1. 음성 인식기에서 발생 하는 이벤트는 백그라운드 스레드에서 발생 하므로 UI 스레드에 대 한 업데이트에 대 한 디스패처 참조를 만듭니다.Because events raised by the speech recognizer occur on a background thread, create a reference to the dispatcher for updates to the UI thread. OnNavigatedTo 는 항상 UI 스레드에서 호출 됩니다.OnNavigatedTo is always invoked on the UI thread.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. 그런 다음 SpeechRecognizer 인스턴스를 초기화 합니다.We then initialize the SpeechRecognizer instance.
this.speechRecognizer = new SpeechRecognizer();
  1. 그런 다음 SpeechRecognizer에서 인식할 수 있는 모든 단어와 구를 정의 하는 문법을 추가 하 고 컴파일합니다.We then add and compile the grammar that defines all of the words and phrases that can be recognized by the SpeechRecognizer.

    문법을 명시적으로 지정 하지 않으면 기본적으로 미리 정의 된 받아쓰기 문법이 사용 됩니다.If you don't specify a grammar explicitly, a predefined dictation grammar is used by default. 일반적으로 기본 문법이 일반 받아쓰기에 가장 적합합니다.Typically, the default grammar is best for general dictation.

    여기서는 문법을 추가 하지 않고 즉시 CompileConstraintsAsync 를 호출 합니다.Here, we call CompileConstraintsAsync immediately without adding a grammar.

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

인식 이벤트 처리Handle recognition events

RecognizeAsync 또는 RecognizeWithUIAsync를 호출 하 여 단일 brief utterance 또는 구를 캡처할 수 있습니다.You can capture a single, brief utterance or phrase by calling RecognizeAsync or RecognizeWithUIAsync.

그러나 더 긴 연속 인식 세션을 캡처하려면 사용자가 받아쓰기 문자열을 작성 하는 처리기를 지정 하 고 정의할 때 백그라운드에서 실행할 이벤트 수신기를 지정 합니다.However, to capture a longer, continuous recognition session, we specify event listeners to run in the background as the user speaks and define handlers to build the dictation string.

그런 다음 인식기의 ContinuousRecognitionSession 속성을 사용 하 여 연속 인식 세션을 관리 하기 위한 메서드 및 이벤트를 제공 하는 SpeechContinuousRecognitionSession 개체를 가져옵니다.We then use the ContinuousRecognitionSession property of our recognizer to obtain a SpeechContinuousRecognitionSession object that provides methods and events for managing a continuous recognition session.

특히 중요 한 두 가지 이벤트는 다음과 같습니다.Two events in particular are critical:

  • 인식기에서 일부 결과를 생성할 때 발생 하는 Resultgenerated입니다.ResultGenerated, which occurs when the recognizer has generated some results.
  • 연속 인식 세션이 종료 될 때 발생 하는 완료된입니다.Completed, which occurs when the continuous recognition session has ended.

사용자가 말하는 대로 Resultgenerated 이벤트가 발생 합니다.The ResultGenerated event is raised as the user speaks. 인식기는 지속적으로 사용자를 수신 하 고 음성 입력의 청크를 전달 하는 이벤트를 주기적으로 발생 시킵니다.The recognizer continuously listens to the user and periodically raises an event that passes a chunk of speech input. 이벤트 인수의 Result 속성을 사용 하 여 음성 입력을 검사 하 고, StringBuilder 개체에 텍스트를 추가 하는 것과 같이 이벤트 처리기에서 적절 한 작업을 수행 해야 합니다.You must examine the speech input, using the Result property of the event argument, and take appropriate action in the event handler, such as appending the text to a StringBuilder object.

SpeechRecognitionResult의 인스턴스인 Result 속성은 음성 입력을 수락할지 여부를 결정 하는 데 유용 합니다.As an instance of SpeechRecognitionResult, the Result property is useful for determining whether you want to accept the speech input. SpeechRecognitionResult 는 다음과 같은 두 가지 속성을 제공 합니다.A SpeechRecognitionResult provides two properties for this:

  • 상태 인식이 성공 했는지 여부를 나타냅니다.Status indicates whether the recognition was successful. 다양 한 이유로 인식이 실패할 수 있습니다.Recognition can fail for a variety of reasons.
  • 신뢰도 는 인식기가 올바른 단어를 이해 했다는 상대적 신뢰도를 나타냅니다.Confidence indicates the relative confidence that the recognizer understood the correct words.

연속 인식을 지원 하기 위한 기본 단계는 다음과 같습니다.Here are the basic steps for supporting continuous recognition:

  1. 여기서는 OnNavigatedTo page 이벤트에서 resultgenerated 연속 인식 이벤트에 대 한 처리기를 등록 합니다.Here, we register the handler for the ResultGenerated continuous recognition event in the OnNavigatedTo page event.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. 그런 다음 신뢰도 속성을 확인 합니다.We then check the Confidence property. 신뢰도 값이 Medium 이상이 면 StringBuilder에 텍스트를 추가 합니다.If the value of Confidence is Medium or better, we append the text to the StringBuilder. 또한 입력을 수집할 때 UI를 업데이트 합니다.We also update the UI as we collect input.

    참고    Resultgenerated 이벤트는 UI를 직접 업데이트할 수 없는 백그라운드 스레드에서 발생 합니다.Note  the ResultGenerated event is raised on a background thread that cannot update the UI directly. 처리기가 UI를 업데이트 해야 하는 경우 ( [ 음성 및 TTS 샘플에서 ] ) 디스패처의 runasync 메서드를 통해 ui 스레드에 대 한 업데이트를 발송 해야 합니다.If a handler needs to update the UI (as the [Speech and TTS sample] does), you must dispatch the updates to the UI thread through the RunAsync method of the dispatcher.

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 이벤트를 처리 합니다.We then handle the Completed event, which indicates the end of continuous dictation.

    다음 섹션에 설명 된 Stopasync 또는 CancelAsync 메서드를 호출 하면 세션이 종료 됩니다.The session ends when you call the StopAsync or CancelAsync methods (described the next section). 오류가 발생 하거나 사용자가 말하기를 중지 한 경우에도 세션이 종료 될 수 있습니다.The session can also end when an error occurs, or when the user has stopped speaking. 이벤트 인수의 Status 속성을 확인 하 여 세션이 종료 된 이유를 확인 합니다 (SpeechRecognitionResultStatus).Check the Status property of the event argument to determine why the session ended (SpeechRecognitionResultStatus).

    여기에서는 OnNavigatedTo page 이벤트에서 완료 된 연속 인식 이벤트에 대 한 처리기를 등록 합니다.Here, we register the handler for the Completed continuous recognition event in the OnNavigatedTo page event.

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. 이벤트 처리기는 Status 속성을 확인 하 여 인식이 성공 했는지 여부를 확인 합니다.The event handler checks the Status property to determine whether the recognition was successful. 또한 사용자가 말하기를 중지 한 경우를 처리 합니다.It also handles the case where the user has stopped speaking. 대부분의 경우에는 사용자가 말하기를 완료 했다는 것을 의미 하기 때문에 timeoutexceeded 성공적으로 인식 된 것으로 간주 됩니다.Often, a TimeoutExceeded is considered successful recognition as it means the user has finished speaking. 한층 뛰어난 환경을 구현하기 위해 코드에서 이런 경우를 처리해야 합니다.You should handle this case in your code for a good experience.

    참고    Resultgenerated 이벤트는 UI를 직접 업데이트할 수 없는 백그라운드 스레드에서 발생 합니다.Note  the ResultGenerated event is raised on a background thread that cannot update the UI directly. 처리기가 UI를 업데이트 해야 하는 경우 ( [ 음성 및 TTS 샘플에서 ] ) 디스패처의 runasync 메서드를 통해 ui 스레드에 대 한 업데이트를 발송 해야 합니다.If a handler needs to update the UI (as the [Speech and TTS sample] does), you must dispatch the updates to the UI thread through the RunAsync method of the dispatcher.

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";
            });
          }
        }
      }

지속적인 인식 피드백 제공Provide ongoing recognition feedback

사용자가 많은 경우에는 컨텍스트를 사용 하 여 무엇을 하는지 완전히 이해 하는 경우가 많습니다.When people converse, they often rely on context to fully understand what is being said. 마찬가지로, 음성 인식기는 높은 신뢰도 인식 결과를 제공 하기 위해 컨텍스트가 필요할 수 있습니다.Similarly, the speech recognizer often needs context to provide high-confidence recognition results. 예를 들어, "가중치" 및 "대기" 라는 단어는 주변 단어에서 더 많은 컨텍스트를 통해 수집할 수 있을 때까지 구별할 수 없습니다.For example, by themselves, the words "weight" and "wait" are indistinguishable until more context can be gleaned from surrounding words. 인식기가 단어 또는 단어가 올바르게 인식 되었다는 확신을 가질 때까지 Resultgenerated 이벤트를 발생 시 키 지 않습니다.Until the recognizer has some confidence that a word, or words, have been recognized correctly, it will not raise the ResultGenerated event.

이로 인해 사용자가 계속 해 서 사용자에 게 적합 한 환경이 생성 될 수 있으며, 인식기가 Resultgenerated 이벤트를 발생 시킬 수 있을 정도로 충분히 높아질 때까지 결과가 제공 되지 않습니다.This can result in a less than ideal experience for the user as they continue speaking and no results are provided until the recognizer has high enough confidence to raise the ResultGenerated event.

HypothesisGenerated 이벤트를 처리 하 여 이러한 명백한 응답성 부족을 향상 시킵니다.Handle the HypothesisGenerated event to improve this apparent lack of responsiveness. 인식기가 처리 중인 단어에 대 한 잠재적 일치 항목의 새 집합을 생성할 때마다 발생 하는 이벤트입니다.This event is raised whenever the recognizer generates a new set of potential matches for the word being processed. 이벤트 인수는 현재 일치 항목을 포함 하는 가설 속성을 제공 합니다.The event argument provides an Hypothesis property that contains the current matches. 사용자가 계속 해 서 사용자에 게이를 표시 하 여 처리가 여전히 활성 상태를 reassure 합니다.Show these to the user as they continue speaking and reassure them that processing is still active. 신뢰가 높고 인식 결과가 확인 되 면 중간 가설 결과를 resultgenerated 이벤트에 제공 된 최종 결과로 바꿉니다.Once confidence is high and a recognition result has been determined, replace the interim Hypothesis results with the final Result provided in the ResultGenerated event.

여기서는 가상 텍스트와 줄임표 ("...")를 출력 텍스트 상자의현재 값에 추가 합니다.Here, we append the hypothetical text and an ellipsis ("…") to the current value of the output TextBox. 새 가설 생성 되 고 resultgenerated 이벤트에서 최종 결과가 반환 될 때까지 텍스트 상자의 내용이 업데이트 됩니다.The contents of the text box are updated as new hypotheses are generated and until the final results are obtained from the ResultGenerated event.

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;
    });
  }

인식 시작 및 중지Start and stop recognition

인식 세션을 시작 하기 전에 음성 인식기 상태 속성의 값을 확인 합니다.Before starting a recognition session, check the value of the speech recognizer State property. 음성 인식기는 유휴 상태 여야 합니다.The speech recognizer must be in an Idle state.

음성 인식기의 상태를 확인 한 후 음성 인식기의 ContinuousRecognitionSession 속성의 StartAsync 메서드를 호출 하 여 세션을 시작 합니다.After checking the state of the speech recognizer, we start the session by calling the StartAsync method of the speech recognizer's ContinuousRecognitionSession property.

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

인식은 다음과 같은 두 가지 방법으로 중지할 수 있습니다.Recognition can be stopped in two ways:

  • Stopasync 는 보류 중인 모든 인식 이벤트를 완료할 수 있도록 합니다. (resultgenerated 는 보류 중인 모든 인식 작업이 완료 될 때까지 계속 발생 합니다).StopAsync lets any pending recognition events complete (ResultGenerated continues to be raised until all pending recognition operations are complete).
  • CancelAsync 는 인식 세션을 즉시 종료 하 고 보류 중인 결과를 모두 삭제 합니다.CancelAsync terminates the recognition session immediately and discards any pending results.

음성 인식기의 상태를 확인 한 후 음성 인식기의 ContinuousRecognitionSession 속성의 CancelAsync 메서드를 호출 하 여 세션을 중지 합니다.After checking the state of the speech recognizer, we stop the session by calling the CancelAsync method of the speech recognizer's ContinuousRecognitionSession property.

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

참고

Resultgenerated 이벤트는 CancelAsync를 호출한 후에 발생할 수 있습니다.A ResultGenerated event can occur after a call to CancelAsync.
다중 스레딩을 통해 CancelAsync 가 호출 될 때 resultgenerated 이벤트가 여전히 스택에 남아 있을 수 있습니다.Because of multithreading, a ResultGenerated event might still remain on the stack when CancelAsync is called. 그렇다면 Resultgenerated 이벤트가 여전히 발생 합니다.If so, the ResultGenerated event still fires.
인식 세션을 취소할 때 전용 필드를 설정 하는 경우 항상 Resultgenerated 처리기에서 해당 값을 확인 합니다.If you set any private fields when canceling the recognition session, always confirm their values in the ResultGenerated handler. 예를 들어, 세션을 취소할 때 null로 설정 하는 경우 처리기에서 필드를 초기화 한다고 가정 하지 마십시오.For example, don't assume a field is initialized in your handler if you set them to null when you cancel the session.

 

샘플Samples