Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aprenda a captar e reconhecer entradas de discurso de ditado contínuo e de formato longo.
APIs importantes: SpeechContinuousRecognitionSession, ContinuousRecognitionSession
No reconhecimento de voz, aprendeste a capturar e reconhecer entradas de fala relativamente curtas usando os métodos RecognizeAsync ou RecognizeWithUIAsync de um objeto SpeechRerecognizer, por exemplo, ao compor uma mensagem de serviço de mensagens curtas (SMS) ou ao fazer uma pergunta.
Para sessões mais longas e contínuas de reconhecimento de voz, como ditado ou email, utilize a propriedade ContinuousRecognitionSession de um Reconhecedor de Fala para obter um objeto SpeechContinuousRecognitionSession .
Observação
O suporte à linguagem de ditado depende do dispositivo onde a sua aplicação está a correr. Para PCs e portáteis, apenas en-US é reconhecido, enquanto a Xbox e os telemóveis podem reconhecer todas as línguas suportadas pelo reconhecimento de voz. Para mais informações, consulte Especificar a linguagem do reconhecedor de voz.
Configurar
A sua aplicação precisa de alguns objetos para gerir uma sessão de ditado contínua:
- Uma instância de um objeto SpeechRerecognizer .
- Uma referência a um despachante de interface para atualizar a interface durante o ditado.
- Uma forma de acompanhar as palavras acumuladas pelo utilizador.
Aqui, declaramos uma instância SpeechRecognizer como um campo privado da classe code-behind. A tua aplicação precisa de armazenar uma referência noutro local se quiseres que o ditado contínuo persista para além de uma única página de Extensible Application Markup Language (XAML).
private SpeechRecognizer speechRecognizer;
Durante o ditado, o reconhecedor gera eventos a partir de uma thread em segundo plano. Como um thread em segundo plano não pode atualizar diretamente a interface em XAML, a sua aplicação deve usar um despachante para atualizar a interface em resposta a eventos de reconhecimento.
Aqui, declaramos um campo privado que será inicializado mais tarde com o despachante da interface.
// 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;
Para acompanhar o que o utilizador está a dizer, é necessário gerir os eventos de reconhecimento gerados pelo reconhecedor de voz. Estes eventos fornecem os resultados de reconhecimento para blocos de enunciações do utilizador.
Aqui, usamos um objeto StringBuilder para armazenar todos os resultados de reconhecimento obtidos durante a sessão. Novos resultados são anexados ao StringBuilder à medida que são processados.
private StringBuilder dictatedTextBuilder;
Inicialização
Durante a inicialização do reconhecimento de fala contínuo, deve:
- Busca o despachante para o tópico da interface se atualizares a interface da tua aplicação nos gestores de eventos de reconhecimento contínuo.
- Inicialize o reconhecedor de fala.
- Compila a gramática de ditado incorporada. Nota O reconhecimento de fala requer pelo menos uma restrição para definir um vocabulário reconhecível. Se não for especificada nenhuma restrição, utiliza-se uma gramática de ditado pré-definida. Ver Reconhecimento de Fala.
- Prepare os ouvintes do evento para eventos de reconhecimento.
Neste exemplo, inicializamos o reconhecimento de fala no evento da página OnNavigatedTo .
- Como os eventos gerados pelo reconhecedor de fala ocorrem numa thread em segundo plano, crie uma referência ao dispatcher para atualizações na thread da interface. OnNavigatedTo é sempre invocado na thread da interface de utilizador.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
- Depois inicializamos a instância do SpeechRerecognizer .
this.speechRecognizer = new SpeechRecognizer();
Depois adicionamos e compilamos a gramática que define todas as palavras e frases que podem ser reconhecidas pelo SpeechRecognizer.
Se não especificares explicitamente uma gramática, uma gramática de ditado pré-definida é usada por defeito. Normalmente, a gramática padrão é a melhor para ditado geral.
Aqui, chamamos CompileConstraintsAsync sem adicionar gramática, imediatamente.
SpeechRecognitionCompilationResult result =
await speechRecognizer.CompileConstraintsAsync();
Processar eventos de reconhecimento
Pode capturar uma única frase ou frase breve chamando RecognizeAsync ou RecognizeWithUIAsync.
No entanto, para captar uma sessão de reconhecimento contínua e mais longa, especificamos ouvintes de eventos para serem executados em segundo plano enquanto o utilizador fala e definimos manipuladores para construir o texto de ditado.
De seguida, usamos a propriedade ContinuousRecognitionSession do nosso reconhecedor para obter um objeto SpeechContinuousRecognitionSession que fornece métodos e eventos para gerir uma sessão de reconhecimento contínuo.
Dois eventos em particular são críticos:
- ResultGenerated, que ocorre quando o reconhecedor gera alguns resultados.
- Concluído, que ocorre quando a sessão de reconhecimento contínua termina.
O evento ResultGenerated é ativado à medida que o utilizador fala. O reconhecedor ouve continuamente o utilizador e periodicamente gera um evento que transmite um segmento da entrada de voz. Deve examinar a entrada de voz, usando a propriedade Result do argumento do evento, e tomar as ações apropriadas no gestor de eventos, como anexar o texto a um objeto StringBuilder.
Como uma instância de SpeechRecognitionResult, a propriedade Result é útil para determinar se quer aceitar a entrada de voz. Um SpeechRecognitionResult fornece duas propriedades para isto:
- O estado indica se o reconhecimento foi bem-sucedido. O reconhecimento pode falhar por várias razões.
- Confiança indica a confiança relativa de que o reconhecedor compreendeu as palavras corretas.
Aqui estão os passos básicos para apoiar o reconhecimento contínuo:
- Aqui, registamos o processador para o evento de reconhecimento contínuo ResultGenerated no evento da página OnNavigatedTo.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
ContinuousRecognitionSession_ResultGenerated;
Depois verificamos a propriedade Confiança . Se o valor de Confiança for Médio ou melhor, adicionamos o texto ao StringBuilder. Também atualizamos a interface à medida que recolhemos entradas.
Note que o evento ResultGenerated é gerado numa thread em segundo plano que não pode atualizar diretamente a interface. Se um handler precisar de atualizar a interface (como o [exemplo de fala e TTS]), deve despachar as atualizações para o thread da interface através do método RunAsync do despachante.
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();
});
}
}
Depois tratamos do evento Completado , que indica o fim do ditado contínuo.
A sessão termina quando chama os métodos StopAsync ou CancelAsync (descritos na secção seguinte). A sessão também pode terminar quando ocorre um erro ou quando o utilizador deixa de falar. Verifique a propriedade Status do argumento do evento para determinar porque terminou a sessão (SpeechRecognitionResultStatus).
Aqui, registamos o manipulador do evento Concluído de reconhecimento contínuo no evento OnNavigatedTo da página.
speechRecognizer.ContinuousRecognitionSession.Completed +=
ContinuousRecognitionSession_Completed;
O gestor de eventos verifica a propriedade Status para determinar se o reconhecimento foi bem-sucedido. Também trata do caso em que o utilizador deixou de falar. Muitas vezes, um TimeoutExceeded é considerado reconhecimento bem-sucedido, pois significa que o utilizador terminou de falar. Deves gerir este caso no teu código para teres uma boa experiência.
Note que o evento ResultGenerated é gerado numa thread em segundo plano que não pode atualizar diretamente a interface. Se um handler precisar de atualizar a interface (como o [exemplo de fala e TTS]), deve despachar as atualizações para o thread da interface através do método RunAsync do despachante.
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";
});
}
}
}
Fornecer reconhecimento contínuo através de feedback
Quando as pessoas conversam, muitas vezes dependem do contexto para compreender totalmente o que está a ser dito. De forma semelhante, o reconhecedor de fala muitas vezes necessita de contexto para fornecer resultados de reconhecimento de alta confiança. Por exemplo, isoladamente, as palavras "peso" e "esperar" são indistinguíveis até que se possa obter mais contexto das palavras circundantes. Até que o reconhecedor tenha alguma confiança de que uma palavra, ou palavras, foram reconhecidas corretamente, não irá disparar o evento ResultGenerated.
Isto pode resultar numa experiência menos ideal para o utilizador, ao continuar a falar, e não são fornecidos resultados até que o reconhecedor tenha confiança suficiente para ativar o evento ResultGenerated.
Lidar com o evento Gerado pela Hipótese para melhorar esta aparente falta de resposta. Este evento é acionado sempre que o reconhecedor gera um novo conjunto de potenciais correspondências para a palavra a ser processada. O argumento do evento fornece uma propriedade Hipótese que contém as correspondências atuais. Mostre-os ao utilizador enquanto continua a falar e tranquilize-o de que o processamento continua ativo. Quando a confiança é elevada e um resultado de reconhecimento tem sido determinado, substitua os resultados intermédios da Hipótese pelo resultado final fornecido no evento ResultGerado .
Aqui, acrescentamos o texto hipotético e uma reticência ("...") ao valor atual da TextBox de saída. O conteúdo da caixa de texto é atualizado à medida que novas hipóteses são geradas e até que os resultados finais sejam obtidos a partir do evento 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;
});
}
Reconhecimento de início e fim
Antes de iniciar uma sessão de reconhecimento, verifique o valor da propriedade de Estado do reconhecimento de voz. O reconhecedor de fala deve estar em estado de inatividade .
Após verificar o estado do reconhecedor de voz, iniciamos a sessão chamando o método StartAsync da propriedade ContinuousRecognitionSession do reconhecedor de voz.
if (speechRecognizer.State == SpeechRecognizerState.Idle)
{
await speechRecognizer.ContinuousRecognitionSession.StartAsync();
}
O reconhecimento pode ser impedido de duas formas:
- O StopAsync permite que quaisquer eventos de reconhecimento pendentes sejam concluídos (o ResultGenerated continua a ser aumentado até que todas as operações de reconhecimento pendentes estejam concluídas).
- O CancelAsync termina imediatamente a sessão de reconhecimento e descarta quaisquer resultados pendentes.
Após verificar o estado do reconhecedor de voz, interrompemos a sessão chamando o método CancelAsync da propriedade ContinuousRecognitionSession do reconhecedor de voz.
if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
await speechRecognizer.ContinuousRecognitionSession.CancelAsync();
}
Observação
Um evento ResultGenerated pode ocorrer após uma chamada ao CancelAsync.
Devido ao multithreading, um evento ResultGenerated pode continuar a permanecer na pilha quando CancelAsync é chamado. Se sim, o evento ResultGenerated continua a ser ativado.
Se definires algum campo privado ao cancelar a sessão de reconhecimento, confirma sempre os seus valores no handler ResultGenerated . Por exemplo, não assumas que um campo está inicializado no teu handler se os definires como null quando cancelares a sessão.
Artigos relacionados
Amostras
Windows developer