Início Rápido: Reconhecer e verificar quem está falando

Documentação de referênciaPacotes (NuGet)Exemplos adicionais no GitHub

Neste início rápido, você aprenderá os padrões de design básicos para reconhecimento de locutor usando o SDK de Fala, incluindo:

  • Verificação dependente do texto e independente do texto.
  • Identificação de locutor para identificar uma amostra de voz em meio a um grupo de vozes.
  • Exclusão de perfis de voz.

Para ter uma visão de alto nível dos conceitos de reconhecimento de locutor, confira o artigo de Visão geral. Consulte o nó Referência na barra de navegação esquerda para obter uma lista das plataformas com suporte.

Importante

A Microsoft limita o acesso ao reconhecimento de locutor. Inscreva-se para usá-los no formulário de Revisão do Acesso Limitado do Reconhecimento de Locutor dos Serviços de IA do Azure. Após a aprovação, você pode acessar as APIs de Reconhecimento do Locutor.

Pré-requisitos

Instalar o SDK de Fala

Antes de começar, você deve instalar o SDK de Fala. Dependendo de sua plataforma, use as seguintes instruções:

Importar dependências

Para executar os exemplos neste artigo, inclua as instruções using a seguir na parte superior do script:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

Criar uma configuração de Fala

Para chamar o serviço de fala usando o SDK de Fala, você precisa criar uma instância SpeechConfig. Neste exemplo, você cria uma instância SpeechConfig usando uma chave de assinatura e uma região. Você também cria um código clichê básico a ser usado no restante do artigo e o modifica para personalizações diferentes.

Importante

Lembre-se de remover a chave do seu código quando terminar e nunca poste-a publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo sobre segurança do serviços de IA do Azure para obter mais informações.

public class Program 
{
    static async Task Main(string[] args)
    {
        // replace with your own subscription key 
        string subscriptionKey = "YourSubscriptionKey";
        // replace with your own subscription region 
        string region = "YourSubscriptionRegion";
        var config = SpeechConfig.FromSubscription(subscriptionKey, region);
    }
}

Verificação dependente do texto

A Verificação do Locutor é o ato de confirmar que um locutor corresponde a uma voz conhecida ou registrada. A primeira etapa é registrar um perfil de voz para que o serviço tenha algo com que comparar as futuras amostras de voz. Neste exemplo, você registra o perfil usando uma estratégia dependente do texto, que requer uma frase secreta específica a ser usada para o registro e a verificação. Confira os documentos de referência para obter uma lista de frases secretas compatíveis.

Comece criando a seguinte função em sua classe Program para registrar um perfil de voz:

public static async Task VerificationEnroll(SpeechConfig config, Dictionary<string, string> profileMapping)
{
    using (var client = new VoiceProfileClient(config))
    using (var profile = await client.CreateProfileAsync(VoiceProfileType.TextDependentVerification, "en-us"))
    {
        var phraseResult = await client.GetActivationPhrasesAsync(VoiceProfileType.TextDependentVerification, "en-us");
        using (var audioInput = AudioConfig.FromDefaultMicrophoneInput())
        {
            Console.WriteLine($"Enrolling profile id {profile.Id}.");
            // give the profile a human-readable display name
            profileMapping.Add(profile.Id, "Your Name");

            VoiceProfileEnrollmentResult result = null;
            while (result is null || result.RemainingEnrollmentsCount > 0)
            {
                Console.WriteLine($"Speak the passphrase, \"${phraseResult.Phrases[0]}\"");
                result = await client.EnrollProfileAsync(profile, audioInput);
                Console.WriteLine($"Remaining enrollments needed: {result.RemainingEnrollmentsCount}");
                Console.WriteLine("");
            }
            
            if (result.Reason == ResultReason.EnrolledVoiceProfile)
            {
                await SpeakerVerify(config, profile, profileMapping);
            }
            else if (result.Reason == ResultReason.Canceled)
            {
                var cancellation = VoiceProfileEnrollmentCancellationDetails.FromResult(result);
                Console.WriteLine($"CANCELED {profile.Id}: ErrorCode={cancellation.ErrorCode} ErrorDetails={cancellation.ErrorDetails}");
            }
        }
    }
}

Nessa função, await client.CreateProfileAsync() é o que realmente cria o perfil de voz. Após a criação, você deverá especificar como vai inserir amostras de áudio, usando AudioConfig.FromDefaultMicrophoneInput() neste exemplo para capturar o áudio do seu dispositivo de entrada padrão. Em seguida, você registra as amostras de áudio em um loop while que acompanha o número de amostras restantes e necessárias para o registro. Em cada iteração, client.EnrollProfileAsync(profile, audioInput) solicitará que você fale a frase secreta no microfone e adicione a amostra ao perfil de voz.

Após a conclusão do registro, chame await SpeakerVerify(config, profile, profileMapping) para verificar em relação ao perfil que você acabou de criar. Adicione outra função para definir SpeakerVerify.

public static async Task SpeakerVerify(SpeechConfig config, VoiceProfile profile, Dictionary<string, string> profileMapping)
{
    var speakerRecognizer = new SpeakerRecognizer(config, AudioConfig.FromDefaultMicrophoneInput());
    var model = SpeakerVerificationModel.FromProfile(profile);

    Console.WriteLine("Speak the passphrase to verify: \"My voice is my passport, please verify me.\"");
    var result = await speakerRecognizer.RecognizeOnceAsync(model);
    Console.WriteLine($"Verified voice profile for speaker {profileMapping[result.ProfileId]}, score is {result.Score}");
}

Nessa função, você passa o objeto VoiceProfile que acabou de criar para inicializar um modelo em relação ao qual verificar. Em seguida, await speakerRecognizer.RecognizeOnceAsync(model) solicita que você fale a frase secreta novamente. Desta vez, ele o valida em seu perfil de voz e retorna uma pontuação de similaridade que varia de 0,0 a 1,0. O objeto result também retornará Accept ou Reject, dependendo da correspondência (ou não) da frase secreta.

Em seguida, modifique sua função Main() para chamar as novas funções que você criou. Além disso, observe que você cria uma Dictionary<string, string> para passar por referência por meio de suas chamadas de função. O motivo disso é que o serviço não permite o armazenamento de um nome legível com um VoiceProfile criado e armazena apenas um número de ID para fins de privacidade. Na função VerificationEnroll, você adiciona a esse dicionário uma entrada com a ID recém-criada, juntamente com um nome de texto. Em cenários de desenvolvimento de aplicativos que exigirem a exibição de um nome legível, você deverá armazenar esse mapeamento em algum lugar porque o serviço não poderá armazená-lo.

static async Task Main(string[] args)
{
    string subscriptionKey = "YourSubscriptionKey";
    string region = "westus";
    var config = SpeechConfig.FromSubscription(subscriptionKey, region);

    // persist profileMapping if you want to store a record of who the profile is
    var profileMapping = new Dictionary<string, string>();
    await VerificationEnroll(config, profileMapping);

    Console.ReadLine();
}

Execute o script. Você será solicitado a falar a frase “Minha voz é meu passaporte, verifique-me!” três vezes para registro e mais uma vez para verificação. O resultado retornado é a pontuação de similaridade, que pode ser usada para criar seus próprios limites personalizados de verificação.

Enrolling profile id 87-2cef-4dff-995b-dcefb64e203f.
Speak the passphrase, "My voice is my passport, verify me."
Remaining enrollments needed: 2

Speak the passphrase, "My voice is my passport, verify me."
Remaining enrollments needed: 1

Speak the passphrase, "My voice is my passport, verify me."
Remaining enrollments needed: 0

Speak the passphrase to verify: "My voice is my passport, verify me."
Verified voice profile for speaker Your Name, score is 0.915581

Verificação independente do texto

Diferente da verificação dependente do texto, a verificação independente do texto não requer três amostras de áudio, mas requer 20 segundos de áudio no total.

Faça algumas alterações simples na função VerificationEnroll para mudar para a verificação independente do texto. Primeiro, altere o tipo de verificação para VoiceProfileType.TextIndependentVerification. Em seguida, altere o loop while para acompanhar result.RemainingEnrollmentsSpeechLength, que continuará solicitando que você fale até completar os 20 segundos de áudio capturados.

public static async Task VerificationEnroll(SpeechConfig config, Dictionary<string, string> profileMapping)
{
    using (var client = new VoiceProfileClient(config))
    using (var profile = await client.CreateProfileAsync(VoiceProfileType.TextIndependentVerification, "en-us"))
    {
        var phraseResult = await client.GetActivationPhrasesAsync(VoiceProfileType.TextIndependentVerification, "en-us");
        using (var audioInput = AudioConfig.FromDefaultMicrophoneInput())
        {
            Console.WriteLine($"Enrolling profile id {profile.Id}.");
            // give the profile a human-readable display name
            profileMapping.Add(profile.Id, "Your Name");

            VoiceProfileEnrollmentResult result = null;
            while (result is null || result.RemainingEnrollmentsSpeechLength > TimeSpan.Zero)
            {
                Console.WriteLine($"Speak the activation phrase, \"${phraseResult.Phrases[0]}\"");
                result = await client.EnrollProfileAsync(profile, audioInput);
                Console.WriteLine($"Remaining enrollment audio time needed: {result.RemainingEnrollmentsSpeechLength}");
                Console.WriteLine("");
            }
            
            if (result.Reason == ResultReason.EnrolledVoiceProfile)
            {
                await SpeakerVerify(config, profile, profileMapping);
            }
            else if (result.Reason == ResultReason.Canceled)
            {
                var cancellation = VoiceProfileEnrollmentCancellationDetails.FromResult(result);
                Console.WriteLine($"CANCELED {profile.Id}: ErrorCode={cancellation.ErrorCode} ErrorDetails={cancellation.ErrorDetails}");
            }
        }
    }
}

Execute o programa novamente e a pontuação de similaridade será retornada.

Enrolling profile id 4tt87d4-f2d3-44ae-b5b4-f1a8d4036ee9.
Speak the activation phrase, "<FIRST ACTIVATION PHRASE>"
Remaining enrollment audio time needed: 00:00:15.3200000

Speak the activation phrase, "<FIRST ACTIVATION PHRASE>"
Remaining enrollment audio time needed: 00:00:09.8100008

Speak the activation phrase, "<FIRST ACTIVATION PHRASE>"
Remaining enrollment audio time needed: 00:00:05.1900000

Speak the activation phrase, "<FIRST ACTIVATION PHRASE>"
Remaining enrollment audio time needed: 00:00:00.8700000

Speak the activation phrase, "<FIRST ACTIVATION PHRASE>"
Remaining enrollment audio time needed: 00:00:00

Speak the passphrase to verify: "My voice is my passport, please verify me."
Verified voice profile for speaker Your Name, score is 0.849409

Identificação do locutor

A Identificação do Locutor é usada para determinar quem está falando dentre um determinado grupo de vozes registradas. O processo é semelhante à verificação independente de texto. A principal diferença é a capacidade de verificar vários perfis de voz ao mesmo tempo em vez de verificar em relação a um único perfil.

Crie uma função IdentificationEnroll para registrar vários perfis de voz. O processo de registro para cada perfil é o mesmo que o processo de registro para verificação independente de texto. O processo requer 20 segundos de áudio para cada perfil. Essa função aceita uma lista de cadeias de caracteres profileNames e criará um perfil de voz para cada nome na lista. A função retorna uma lista de objetos VoiceProfile, que você usa na próxima função para identificar um locutor.

public static async Task<List<VoiceProfile>> IdentificationEnroll(SpeechConfig config, List<string> profileNames, Dictionary<string, string> profileMapping)
{
    List<VoiceProfile> voiceProfiles = new List<VoiceProfile>();
    using (var client = new VoiceProfileClient(config))
    {
        var phraseResult = await client.GetActivationPhrasesAsync(VoiceProfileType.TextIndependentVerification, "en-us");
        foreach (string name in profileNames)
        {
            using (var audioInput = AudioConfig.FromDefaultMicrophoneInput())
            {
                var profile = await client.CreateProfileAsync(VoiceProfileType.TextIndependentIdentification, "en-us");
                Console.WriteLine($"Creating voice profile for {name}.");
                profileMapping.Add(profile.Id, name);

                VoiceProfileEnrollmentResult result = null;
                while (result is null || result.RemainingEnrollmentsSpeechLength > TimeSpan.Zero)
                {
                    Console.WriteLine($"Speak the activation phrase, \"${phraseResult.Phrases[0]}\" to add to the profile enrollment sample for {name}.");
                    result = await client.EnrollProfileAsync(profile, audioInput);
                    Console.WriteLine($"Remaining enrollment audio time needed: {result.RemainingEnrollmentsSpeechLength}");
                    Console.WriteLine("");
                }
                voiceProfiles.Add(profile);
            }
        }
    }
    return voiceProfiles;
}

Crie a função SpeakerIdentification a seguir para enviar uma solicitação de identificação. A principal diferença dessa função em relação à uma solicitação de verificação do locutor é o uso de SpeakerIdentificationModel.FromProfiles(), que aceita uma lista de objetos VoiceProfile.

public static async Task SpeakerIdentification(SpeechConfig config, List<VoiceProfile> voiceProfiles, Dictionary<string, string> profileMapping) 
{
    var speakerRecognizer = new SpeakerRecognizer(config, AudioConfig.FromDefaultMicrophoneInput());
    var model = SpeakerIdentificationModel.FromProfiles(voiceProfiles);

    Console.WriteLine("Speak some text to identify who it is from your list of enrolled speakers.");
    var result = await speakerRecognizer.RecognizeOnceAsync(model);
    Console.WriteLine($"The most similar voice profile is {profileMapping[result.ProfileId]} with similarity score {result.Score}");
}

Altere a função Main() conforme a seguir. Você cria uma lista de cadeias de caracteres profileNames e passa ela para a função IdentificationEnroll(). Você será solicitado a criar um perfil de voz para cada nome da lista, de modo que você possa adicionar mais nomes a fim de criar mais perfis para amigos ou colegas.

static async Task Main(string[] args)
{
    // replace with your own subscription key 
    string subscriptionKey = "YourSubscriptionKey";
    // replace with your own subscription region 
    string region = "YourSubscriptionRegion";
    var config = SpeechConfig.FromSubscription(subscriptionKey, region);

    // persist profileMapping if you want to store a record of who the profile is
    var profileMapping = new Dictionary<string, string>();
    var profileNames = new List<string>() { "Your name", "A friend's name" };
    
    var enrolledProfiles = await IdentificationEnroll(config, profileNames, profileMapping);
    await SpeakerIdentification(config, enrolledProfiles, profileMapping);

    foreach (var profile in enrolledProfiles)
    {
        profile.Dispose();
    }
    Console.ReadLine();
}

Execute o script. Você será solicitado a falar para registrar as amostras de voz para o primeiro perfil. Depois que o registro for concluído, será solicitado que você repita esse processo para cada nome da lista profileNames. Depois que cada registro for concluído, você será solicitado a fazer com que uma das pessoas fale. Em seguida, o serviço tenta identificar essa pessoa entre seus perfis de voz inscritos.

Este exemplo retorna apenas a combinação mais próxima e sua pontuação de similaridade. Para obter a resposta completa que inclui as cinco principais pontuações de similaridade, adicione string json = result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult) à sua função SpeakerIdentification.

Alterar o tipo de entrada de áudio

Os exemplos deste artigo usam o microfone de dispositivo padrão como o meio de entrada das amostras de áudio. Em cenários que exijam o uso de arquivos de áudio em vez da entrada por meio do microfone, altere as instâncias de AudioConfig.FromDefaultMicrophoneInput() para AudioConfig.FromWavFileInput(path/to/your/file.wav) a fim de alternar para a entrada por meio de arquivo. Também é possível ter entradas mistas usando o microfone para registro e arquivos para verificação, por exemplo.

Excluir registros de perfis de voz

Para excluir um perfil registrado, use a função DeleteProfileAsync() no objeto VoiceProfileClient. O exemplo de função a seguir mostra como excluir um perfil de voz de uma ID de perfil de voz conhecida:

public static async Task DeleteProfile(SpeechConfig config, string profileId) 
{
    using (var client = new VoiceProfileClient(config))
    {
        var profile = new VoiceProfile(profileId);
        await client.DeleteProfileAsync(profile);
    }
}

Documentação de referênciaPacotes (NuGet)Exemplos adicionais no GitHub

Neste início rápido, você aprenderá os padrões de design básicos para reconhecimento de locutor usando o SDK de Fala, incluindo:

  • Verificação dependente do texto e independente do texto.
  • Identificação de locutor para identificar uma amostra de voz em meio a um grupo de vozes.
  • Exclusão de perfis de voz.

Para ter uma visão de alto nível dos conceitos de reconhecimento de locutor, confira o artigo de Visão geral. Consulte o nó Referência na barra de navegação esquerda para obter uma lista das plataformas com suporte.

Importante

A Microsoft limita o acesso ao reconhecimento de locutor. Inscreva-se para usá-los no formulário de Revisão do Acesso Limitado do Reconhecimento de Locutor dos Serviços de IA do Azure. Após a aprovação, você pode acessar as APIs de Reconhecimento do Locutor.

Pré-requisitos

Instalar o SDK de Fala

Antes de começar, você deve instalar o SDK de Fala. Dependendo de sua plataforma, use as seguintes instruções:

Importar dependências

Para executar os exemplos neste artigo, adicione as instruções a seguir na parte superior do seu arquivo .cpp:

#include <iostream>
#include <stdexcept>
// Note: Install the NuGet package Microsoft.CognitiveServices.Speech.
#include <speechapi_cxx.h>

using namespace std;
using namespace Microsoft::CognitiveServices::Speech;

// Note: Change the locale if desired.
auto profile_locale = "en-us";
auto audio_config = Audio::AudioConfig::FromDefaultMicrophoneInput();
auto ticks_per_second = 10000000;

Criar uma configuração de Fala

Para chamar o serviço de Fala usando o SDK de Fala, crie uma classe SpeechConfig. Essa classe inclui informações sobre sua assinatura, como sua chave e região, ponto de extremidade, host ou token de autorização associados.

Importante

Lembre-se de remover a chave do seu código quando terminar e nunca poste-a publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo sobre segurança do serviços de IA do Azure para obter mais informações.

shared_ptr<SpeechConfig> GetSpeechConfig()
{
    auto subscription_key = 'PASTE_YOUR_SPEECH_SUBSCRIPTION_KEY_HERE';
    auto region = 'PASTE_YOUR_SPEECH_ENDPOINT_REGION_HERE';
    auto config = SpeechConfig::FromSubscription(subscription_key, region);
    return config;
}

Verificação dependente do texto

A Verificação do Locutor é o ato de confirmar que um locutor corresponde a uma voz conhecida ou registrada. A primeira etapa é registrar um perfil de voz para que o serviço tenha algo com que comparar as futuras amostras de voz. Neste exemplo, você registra o perfil usando uma estratégia dependente do texto, que requer uma frase secreta específica a ser usada para o registro e a verificação. Confira os documentos de referência para obter uma lista de frases secretas compatíveis.

Função TextDependentVerification

Comece criando a função TextDependentVerification:

void TextDependentVerification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
    std::cout << "Text Dependent Verification:\n\n";
    // Create the profile.
    auto profile = client->CreateProfileAsync(VoiceProfileType::TextDependentVerification, profile_locale).get();
    std::cout << "Created profile ID: " << profile->GetId() << "\n";
    AddEnrollmentsToTextDependentProfile(client, profile);
    SpeakerVerify(profile, recognizer);
    // Delete the profile.
    client->DeleteProfileAsync(profile);
}

Essa função cria um objeto VoiceProfile com o método CreateProfileAsync. Há três tipos de VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

Nesse caso, passe VoiceProfileType::TextDependentVerification para CreateProfileAsync.

Em seguida, chame duas funções auxiliares que você definirá a seguir, AddEnrollmentsToTextDependentProfile e SpeakerVerify. Por fim, chame DeleteProfileAsync para limpar o perfil.

Função AddEnrollmentsToTextDependentProfile

Defina a função a seguir para registrar um perfil de voz:

void AddEnrollmentsToTextDependentProfile(shared_ptr<VoiceProfileClient> client, shared_ptr<VoiceProfile> profile)
{
    shared_ptr<VoiceProfileEnrollmentResult> enroll_result = nullptr;
    auto phraseResult = client->GetActivationPhrasesAsync(profile->GetType(), profile_locale).get();
    auto phrases = phraseResult->GetPhrases();
    while (enroll_result == nullptr || enroll_result->GetEnrollmentInfo(EnrollmentInfoType::RemainingEnrollmentsCount) > 0)
    {
        if (phrases != nullptr && phrases->size() > 0)
        {
            std::cout << "Please say the passphrase, \"" << phrases->at(0) << "\"\n";
            enroll_result = client->EnrollProfileAsync(profile, audio_config).get();
            std::cout << "Remaining enrollments needed: " << enroll_result->GetEnrollmentInfo(EnrollmentInfoType::RemainingEnrollmentsCount) << ".\n";
        }
        else
        {
            std::cout << "No passphrases received, enrollment not attempted.\n\n";
        }
    }
    std::cout << "Enrollment completed.\n\n";
}

Nessa função, você registrará as amostras de áudio em um loop while que acompanha o número de amostras restantes e necessárias para o registro. Em cada iteração, EnrollProfileAsync solicitará que você fale a frase secreta no microfone e adicione a amostra ao perfil de voz.

Função SpeakerVerify

Defina SpeakerVerify da seguinte maneira:

void SpeakerVerify(shared_ptr<VoiceProfile> profile, shared_ptr<SpeakerRecognizer> recognizer)
{
    shared_ptr<SpeakerVerificationModel> model = SpeakerVerificationModel::FromProfile(profile);
    std::cout << "Speak the passphrase to verify: \"My voice is my passport, verify me.\"\n";
    shared_ptr<SpeakerRecognitionResult> result = recognizer->RecognizeOnceAsync(model).get();
    std::cout << "Verified voice profile for speaker: " << result->ProfileId << ". Score is: " << result->GetScore() << ".\n\n";
}

Nesta função, você criará um objeto SpeakerVerificationModel com o método SpeakerVerificationModel::FromProfile, passando o objeto VoiceProfile criado anteriormente.

Em seguida, SpeechRecognizer::RecognizeOnceAsync solicitará que você fale a frase secreta novamente. Desta vez, ele o valida em seu perfil de voz e retorna uma pontuação de similaridade que varia de 0,0 a 1,0. O objeto SpeakerRecognitionResult também retornará Accept ou Reject, com base na correspondência da frase secreta.

Verificação independente do texto

Diferente da verificação dependente do texto, a verificação independente do texto não requer três amostras de áudio, mas requer 20 segundos de áudio no total.

Função TextIndependentVerification

Comece criando a função TextIndependentVerification:

void TextIndependentVerification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
    std::cout << "Text Independent Verification:\n\n";
    // Create the profile.
    auto profile = client->CreateProfileAsync(VoiceProfileType::TextIndependentVerification, profile_locale).get();
    std::cout << "Created profile ID: " << profile->GetId() << "\n";
    AddEnrollmentsToTextIndependentProfile(client, profile);
    SpeakerVerify(profile, recognizer);
    // Delete the profile.
    client->DeleteProfileAsync(profile);
}

Como a função TextDependentVerification, essa função cria um objeto VoiceProfile com o método CreateProfileAsync.

Nesse caso, passe VoiceProfileType::TextIndependentVerification para CreateProfileAsync.

Em seguida, chame duas funções auxiliares: AddEnrollmentsToTextIndependentProfile, que você definirá a seguir, e SpeakerVerify, que você já definiu. Por fim, chame DeleteProfileAsync para limpar o perfil.

AddEnrollmentsToTextIndependentProfile

Defina a função a seguir para registrar um perfil de voz:

void AddEnrollmentsToTextIndependentProfile(shared_ptr<VoiceProfileClient> client, shared_ptr<VoiceProfile> profile)
{
    shared_ptr<VoiceProfileEnrollmentResult> enroll_result = nullptr;
    auto phraseResult = client->GetActivationPhrasesAsync(profile->GetType(), profile_locale).get();
    auto phrases = phraseResult->GetPhrases();
    while (enroll_result == nullptr || enroll_result->GetEnrollmentInfo(EnrollmentInfoType::RemainingEnrollmentsSpeechLength) > 0)
    {
        if (phrases != nullptr && phrases->size() > 0)
        {
            std::cout << "Please say the activation phrase, \"" << phrases->at(0) << "\"\n";
            enroll_result = client->EnrollProfileAsync(profile, audio_config).get();
            std::cout << "Remaining audio time needed: " << enroll_result->GetEnrollmentInfo(EnrollmentInfoType::RemainingEnrollmentsSpeechLength) / ticks_per_second << " seconds.\n";
        }
        else
        {
            std::cout << "No activation phrases received, enrollment not attempted.\n\n";
        }
    }
    std::cout << "Enrollment completed.\n\n";
}

Nessa função, você registrará as amostras de áudio em um loop while que acompanha o número de segundos de áudio restantes e necessários para o registro. Em cada iteração, EnrollProfileAsync solicitará que você fale no microfone e adicione a amostra ao perfil de voz.

Identificação do locutor

A Identificação do Locutor é usada para determinar quem está falando dentre um determinado grupo de vozes registradas. O processo é semelhante à verificação independente de texto. A principal diferença é a capacidade de verificar vários perfis de voz ao mesmo tempo em vez de verificar em relação a um único perfil.

Função TextIndependentIdentification

Comece criando a função TextIndependentIdentification:

void TextIndependentIdentification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
    std::cout << "Speaker Identification:\n\n";
    // Create the profile.
    auto profile = client->CreateProfileAsync(VoiceProfileType::TextIndependentIdentification, profile_locale).get();
    std::cout << "Created profile ID: " << profile->GetId() << "\n";
    AddEnrollmentsToTextIndependentProfile(client, profile);
    SpeakerIdentify(profile, recognizer);
    // Delete the profile.
    client->DeleteProfileAsync(profile);
}

Como as funções TextDependentVerification e TextIndependentVerification, essa função cria um objeto VoiceProfile com o método CreateProfileAsync.

Nesse caso, passe VoiceProfileType::TextIndependentIdentification para CreateProfileAsync.

Em seguida, chame duas funções auxiliares: AddEnrollmentsToTextIndependentProfile, que você já definiu, e SpeakerIdentify, que você definirá em seguida. Por fim, chame DeleteProfileAsync para limpar o perfil.

Função SpeakerIdentify

Defina a função SpeakerIdentify conforme descrito a seguir:

void SpeakerIdentify(shared_ptr<VoiceProfile> profile, shared_ptr<SpeakerRecognizer> recognizer)
{
    shared_ptr<SpeakerIdentificationModel> model = SpeakerIdentificationModel::FromProfiles({ profile });
    // Note: We need at least four seconds of audio after pauses are subtracted.
    std::cout << "Please speak for at least ten seconds to identify who it is from your list of enrolled speakers.\n";
    shared_ptr<SpeakerRecognitionResult> result = recognizer->RecognizeOnceAsync(model).get();
    std::cout << "The most similar voice profile is: " << result->ProfileId << " with similarity score: " << result->GetScore() << ".\n\n";
}

Nessa função, você criará um objeto SpeakerIdentificationModel com o método SpeakerIdentificationModel::FromProfiles. SpeakerIdentificationModel::FromProfiles aceita uma lista de objetos VoiceProfile. Nesse caso, você passará o objeto VoiceProfile criado anteriormente. Se desejar, você poderá passar vários objetos VoiceProfile, cada um registrado com amostras de áudio de uma voz diferente.

Em seguida, SpeechRecognizer::RecognizeOnceAsync solicitará que você fale novamente. Desta vez, ele vai comparar sua voz com os perfis de voz registrados e retornar o perfil de voz mais semelhante.

Função principal

Por fim, defina a função main conforme descrito a seguir:

int main()
{
    auto speech_config = GetSpeechConfig();
    auto client = VoiceProfileClient::FromConfig(speech_config);
    auto recognizer = SpeakerRecognizer::FromConfig(speech_config, audio_config);
    TextDependentVerification(client, recognizer);
    TextIndependentVerification(client, recognizer);
    TextIndependentIdentification(client, recognizer);
    std::cout << "End of quickstart.\n";
}

Essa função chama as funções que você definiu anteriormente. Ela primeiro cria um objeto VoiceProfileClient e um objeto SpeakerRecognizer.

auto speech_config = GetSpeechConfig();
auto client = VoiceProfileClient::FromConfig(speech_config);
auto recognizer = SpeakerRecognizer::FromConfig(speech_config, audio_config);

O objeto VoiceProfileClient é usado para criar, registrar e excluir perfis de voz. O objeto SpeakerRecognizer é usado para validar exemplos de fala em um ou mais perfis de voz registrados.

Alterar o tipo de entrada de áudio

Os exemplos deste artigo usam o microfone de dispositivo padrão como o meio de entrada das amostras de áudio. Em cenários em que você precisa usar arquivos de áudio de entrada por microfone, altere a seguinte linha:

auto audio_config = Audio::AudioConfig::FromDefaultMicrophoneInput();

para:

auto audio_config = Audio::AudioConfig::FromWavFileInput("path/to/your/file.wav");

Ou substitua qualquer uso de audio_config por audio::AudioConfig::FromWavFileInput. Também é possível ter entradas mistas usando o microfone para registro e arquivos para verificação, por exemplo.

Documentação de referênciaPacotes (Go)Exemplos adicionais no GitHub

Neste início rápido, você aprenderá os padrões de design básicos para reconhecimento de locutor usando o SDK de Fala, incluindo:

  • Verificação dependente do texto e independente do texto.
  • Identificação de locutor para identificar uma amostra de voz em meio a um grupo de vozes.
  • Exclusão de perfis de voz.

Para ter uma visão de alto nível dos conceitos de reconhecimento de locutor, confira o artigo de Visão geral. Consulte o nó Referência na barra de navegação esquerda para obter uma lista das plataformas com suporte.

Importante

A Microsoft limita o acesso ao reconhecimento de locutor. Inscreva-se para usá-los no formulário de Revisão do Acesso Limitado do Reconhecimento de Locutor dos Serviços de IA do Azure. Após a aprovação, você pode acessar as APIs de Reconhecimento do Locutor.

Pré-requisitos

Configurar o ambiente

Instalar o SDK de Fala para Go. Verifique o Guia de instalação do SDK para conhecer outros requisitos

Realizar identificação independente

Siga estas etapas para criar um novo módulo GO.

  1. Abra um prompt de comando onde você deseja criar o novo módulo e crie um novo arquivo chamado independent-identification.go.

  2. Substitua o conteúdo de independent-identification.go pelo seguinte código.

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "time"
    
        "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/speaker"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
    )
    
    func GetNewVoiceProfileFromClient(client *speaker.VoiceProfileClient, expectedType common.VoiceProfileType) *speaker.VoiceProfile {
        future := client.CreateProfileAsync(expectedType, "en-US")
        outcome := <-future
        if outcome.Failed() {
            fmt.Println("Got an error creating profile: ", outcome.Error.Error())
            return nil
        }
        profile := outcome.Profile
        _, err := profile.Id()
        if err != nil {
            fmt.Println("Unexpected error creating profile id: ", err)
            return nil
        }
        profileType, err := profile.Type();
        if err != nil {
            fmt.Println("Unexpected error getting profile type: ", err)
            return nil
        }
        if profileType != expectedType {
            fmt.Println("Profile type does not match expected type")
            return nil
        }
        return profile
    }
    
    func EnrollProfile(client *speaker.VoiceProfileClient, profile *speaker.VoiceProfile, audioConfig *audio.AudioConfig) {
        enrollmentReason, currentReason := common.EnrollingVoiceProfile, common.EnrollingVoiceProfile
        var currentResult *speaker.VoiceProfileEnrollmentResult
        expectedEnrollmentCount := 1
        for currentReason == enrollmentReason {
            fmt.Println(`Please speak the following phrase: "I'll talk for a few seconds so you can recognize my voice in the future."`)
            enrollFuture := client.EnrollProfileAsync(profile, audioConfig)
            enrollOutcome := <-enrollFuture
            if enrollOutcome.Failed() {
                fmt.Println("Got an error enrolling profile: ", enrollOutcome.Error.Error())
                return
            }
            currentResult = enrollOutcome.Result
            currentReason = currentResult.Reason
            if currentResult.EnrollmentsCount != expectedEnrollmentCount {
                fmt.Println("Unexpected enrollments for profile: ", currentResult.RemainingEnrollmentsCount)
            }
            expectedEnrollmentCount += 1
        }
        if currentReason != common.EnrolledVoiceProfile {
            fmt.Println("Unexpected result enrolling profile: ", currentResult)
        }
    }
    
    func DeleteProfile(client *speaker.VoiceProfileClient, profile *speaker.VoiceProfile) {
        deleteFuture := client.DeleteProfileAsync(profile)
        deleteOutcome := <-deleteFuture
        if deleteOutcome.Failed() {
            fmt.Println("Got an error deleting profile: ", deleteOutcome.Error.Error())
            return
        }
        result := deleteOutcome.Result
        if result.Reason != common.DeletedVoiceProfile {
            fmt.Println("Unexpected result deleting profile: ", result)
        }
    }
    
    func main() {
        subscription :=  "YourSubscriptionKey"
        region := "YourServiceRegion"
        config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer config.Close()
        client, err := speaker.NewVoiceProfileClientFromConfig(config)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer client.Close()
        audioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer audioConfig.Close()
        <-time.After(10 * time.Second)
        expectedType := common.VoiceProfileType(1)
    
        profile := GetNewVoiceProfileFromClient(client, expectedType)
        if profile == nil {
            fmt.Println("Error creating profile")
            return
        }
        defer profile.Close()
    
        EnrollProfile(client, profile, audioConfig)
    
        profiles := []*speaker.VoiceProfile{profile}
        model, err := speaker.NewSpeakerIdentificationModelFromProfiles(profiles)
        if err != nil {
            fmt.Println("Error creating Identification model: ", err)
        }
        if model == nil {
            fmt.Println("Error creating Identification model: nil model")
            return
        }
        identifyAudioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer identifyAudioConfig.Close()
        speakerRecognizer, err := speaker.NewSpeakerRecognizerFromConfig(config, identifyAudioConfig)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        identifyFuture := speakerRecognizer.IdentifyOnceAsync(model)
        identifyOutcome := <-identifyFuture
        if identifyOutcome.Failed() {
            fmt.Println("Got an error identifying profile: ", identifyOutcome.Error.Error())
            return
        }
        identifyResult := identifyOutcome.Result
        if identifyResult.Reason != common.RecognizedSpeakers {
            fmt.Println("Got an unexpected result identifying profile: ", identifyResult)
        }
        expectedID, _ := profile.Id()
        if identifyResult.ProfileID != expectedID {
            fmt.Println("Got an unexpected profile id identifying profile: ", identifyResult.ProfileID)
        }
        if identifyResult.Score < 1.0 {
            fmt.Println("Got an unexpected score identifying profile: ", identifyResult.Score)
        }
    
        DeleteProfile(client, profile)
        bufio.NewReader(os.Stdin).ReadBytes('\n')
    }
    
  3. Em independent-identification.go, substitua YourSubscriptionKey pela sua chave de recurso de fala e substitua YourServiceRegion pela sua região de recurso de fala.

    Importante

    Lembre-se de remover a chave do seu código quando terminar e nunca poste-a publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo sobre segurança do serviços de IA do Azure para obter mais informações.

Execute os comandos a seguir para criar um arquivo go.mod vinculado aos componentes hospedados no GitHub:

go mod init independent-identification
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Agora compile e execute o código:

go build
go run independent-identification

Realizar verificação independente

Siga estas etapas para criar um novo módulo GO.

  1. Abra um prompt de comando onde você deseja criar o novo módulo e crie um novo arquivo chamado independent-verification.go.

  2. Substitua o conteúdo de independent-verification.go pelo seguinte código.

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "time"
    
        "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/speaker"
        "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
    )
    
    func GetNewVoiceProfileFromClient(client *speaker.VoiceProfileClient, expectedType common.VoiceProfileType) *speaker.VoiceProfile {
        future := client.CreateProfileAsync(expectedType, "en-US")
        outcome := <-future
        if outcome.Failed() {
            fmt.Println("Got an error creating profile: ", outcome.Error.Error())
            return nil
        }
        profile := outcome.Profile
        _, err := profile.Id()
        if err != nil {
            fmt.Println("Unexpected error creating profile id: ", err)
            return nil
        }
        profileType, err := profile.Type();
        if err != nil {
            fmt.Println("Unexpected error getting profile type: ", err)
            return nil
        }
        if profileType != expectedType {
            fmt.Println("Profile type does not match expected type")
            return nil
        }
        return profile
    }
    
    func EnrollProfile(client *speaker.VoiceProfileClient, profile *speaker.VoiceProfile, audioConfig *audio.AudioConfig) {
        enrollmentReason, currentReason := common.EnrollingVoiceProfile, common.EnrollingVoiceProfile
        var currentResult *speaker.VoiceProfileEnrollmentResult
        expectedEnrollmentCount := 1
        for currentReason == enrollmentReason {
            fmt.Println(`Please speak the following phrase: "I'll talk for a few seconds so you can recognize my voice in the future."`)
            enrollFuture := client.EnrollProfileAsync(profile, audioConfig)
            enrollOutcome := <-enrollFuture
            if enrollOutcome.Failed() {
                fmt.Println("Got an error enrolling profile: ", enrollOutcome.Error.Error())
                return
            }
            currentResult = enrollOutcome.Result
            currentReason = currentResult.Reason
            if currentResult.EnrollmentsCount != expectedEnrollmentCount {
                fmt.Println("Unexpected enrollments for profile: ", currentResult.RemainingEnrollmentsCount)
            }
            expectedEnrollmentCount += 1
        }
        if currentReason != common.EnrolledVoiceProfile {
            fmt.Println("Unexpected result enrolling profile: ", currentResult)
        }
    }
    
    func DeleteProfile(client *speaker.VoiceProfileClient, profile *speaker.VoiceProfile) {
        deleteFuture := client.DeleteProfileAsync(profile)
        deleteOutcome := <-deleteFuture
        if deleteOutcome.Failed() {
            fmt.Println("Got an error deleting profile: ", deleteOutcome.Error.Error())
            return
        }
        result := deleteOutcome.Result
        if result.Reason != common.DeletedVoiceProfile {
            fmt.Println("Unexpected result deleting profile: ", result)
        }
    }
    
    func main() {
        subscription :=  "YourSubscriptionKey"
        region := "YourServiceRegion"
        config, err := speech.NewSpeechConfigFromSubscription(subscription, region)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer config.Close()
        client, err := speaker.NewVoiceProfileClientFromConfig(config)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer client.Close()
        audioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer audioConfig.Close()
        <-time.After(10 * time.Second)
        expectedType := common.VoiceProfileType(3)
    
        profile := GetNewVoiceProfileFromClient(client, expectedType)
        if profile == nil {
            fmt.Println("Error creating profile")
            return
        }
        defer profile.Close()
    
        EnrollProfile(client, profile, audioConfig)
    
        model, err := speaker.NewSpeakerVerificationModelFromProfile(profile)
        if err != nil {
            fmt.Println("Error creating Verification model: ", err)
        }
        if model == nil {
            fmt.Println("Error creating Verification model: nil model")
            return
        }
        verifyAudioConfig, err := audio.NewAudioConfigFromDefaultMicrophoneInput()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        defer verifyAudioConfig.Close()
        speakerRecognizer, err := speaker.NewSpeakerRecognizerFromConfig(config, verifyAudioConfig)
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }
        verifyFuture := speakerRecognizer.VerifyOnceAsync(model)
        verifyOutcome := <-verifyFuture
        if verifyOutcome.Failed() {
            fmt.Println("Got an error verifying profile: ", verifyOutcome.Error.Error())
            return
        }
        verifyResult := verifyOutcome.Result
        if verifyResult.Reason != common.RecognizedSpeaker {
            fmt.Println("Got an unexpected result verifying profile: ", verifyResult)
        }
        expectedID, _ := profile.Id()
        if verifyResult.ProfileID != expectedID {
            fmt.Println("Got an unexpected profile id verifying profile: ", verifyResult.ProfileID)
        }
        if verifyResult.Score < 1.0 {
            fmt.Println("Got an unexpected score verifying profile: ", verifyResult.Score)
        }
    
        DeleteProfile(client, profile)
        bufio.NewReader(os.Stdin).ReadBytes('\n')
    }
    
  3. Em independent-verification.go, substitua YourSubscriptionKey pela sua chave de recurso de fala e substitua YourServiceRegion pela sua região de recurso de fala.

Execute os comandos a seguir para criar um arquivo go.mod vinculado aos componentes hospedados no GitHub:

go mod init independent-verification
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Agora compile e execute o código:

go build
go run independent-verification

Limpar os recursos

Você pode usar o portal do Azure ou a CLI (interface de linha de comando) do Azure para remover o recurso de fala que você criou.

Documentação de referência | Amostras adicionais no GitHub

O SDK de Fala para Java dá suporte ao reconhecimento de locutor, mas ainda não incluímos um guia aqui. Selecione outra linguagem de programação para começar e aprenda sobre os conceitos ou consulte a referência e exemplos do Java vinculados no início deste artigo.

Documentação de referênciaPacote (npm)Exemplos adicionais no GitHub Código-fonte de biblioteca

Neste início rápido, você aprenderá os padrões de design básicos para reconhecimento de locutor usando o SDK de Fala, incluindo:

  • Verificação dependente do texto e independente do texto.
  • Identificação de locutor para identificar uma amostra de voz em meio a um grupo de vozes.
  • Exclusão de perfis de voz.

Para ter uma visão de alto nível dos conceitos de reconhecimento de locutor, confira o artigo de Visão geral. Consulte o nó Referência na barra de navegação esquerda para obter uma lista das plataformas com suporte.

Importante

A Microsoft limita o acesso ao reconhecimento de locutor. Inscreva-se para usá-los no formulário de Revisão do Acesso Limitado do Reconhecimento de Locutor dos Serviços de IA do Azure. Após a aprovação, você pode acessar as APIs de Reconhecimento do Locutor.

Pré-requisitos

Instalar o SDK de Fala

Antes de começar, você precisa instalar o SDK de Fala para JavaScript.

Dependendo do ambiente de destino, use um dos seguintes:

Baixe e extraia o arquivo do SDK de Fala para JavaScript microsoft.cognitiveservices.speech.sdk.bundle.js. Coloque-o em uma pasta acessível ao arquivo HTML.

<script src="microsoft.cognitiveservices.speech.sdk.bundle.js"></script>;

Dica

Se estiver direcionando a um navegador da Web e usando a tag <script>, o prefixo sdk não será necessário. O prefixo sdk é um alias usado para dar nome ao módulo require.

Importar dependências

Para executar os exemplos deste artigo, adicione as instruções a seguir na parte superior do seu arquivo .js:

"use strict";

/* To run this sample, install:
npm install microsoft-cognitiveservices-speech-sdk
*/
var sdk = require("microsoft-cognitiveservices-speech-sdk");
var fs = require("fs");

// Note: Change the locale if desired.
const profile_locale = "en-us";

/* Note: passphrase_files and verify_file should contain paths to audio files that contain \"My voice is my passport, verify me.\"
You can obtain these files from:
https://github.com/Azure-Samples/cognitive-services-speech-sdk/tree/fa6428a0837779cbeae172688e0286625e340942/quickstart/javascript/node/speaker-recognition/verification
*/ 
const passphrase_files = ["myVoiceIsMyPassportVerifyMe01.wav", "myVoiceIsMyPassportVerifyMe02.wav", "myVoiceIsMyPassportVerifyMe03.wav"];
const verify_file = "myVoiceIsMyPassportVerifyMe04.wav";
/* Note: identify_file should contain a path to an audio file that uses the same voice as the other files, but contains different speech. You can obtain this file from:
https://github.com/Azure-Samples/cognitive-services-speech-sdk/tree/fa6428a0837779cbeae172688e0286625e340942/quickstart/javascript/node/speaker-recognition/identification
*/
const identify_file = "aboutSpeechSdk.wav";

var subscription_key = 'PASTE_YOUR_SPEECH_SUBSCRIPTION_KEY_HERE';
var region = 'PASTE_YOUR_SPEECH_ENDPOINT_REGION_HERE';

const ticks_per_second = 10000000;

Essas instruções importam as bibliotecas necessárias e obtêm a região e a chave de assinatura do serviço de Fala de suas variáveis de ambiente. Elas também especificam os caminhos para os arquivos de áudio que você usará nas tarefas a seguir.

Importante

Lembre-se de remover a chave do seu código quando terminar e nunca poste-a publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo sobre segurança do serviços de IA do Azure para obter mais informações.

Criar uma função auxiliar

Adicione a função auxiliar a seguir para ler arquivos de áudio em fluxos para uso pelo serviço de Fala:

function GetAudioConfigFromFile (file)
{
    return sdk.AudioConfig.fromWavFileInput(fs.readFileSync(file));
}

Nessa função, você usará os métodos AudioInputStream.createPushStream e AudioConfig.fromStreamInput para criar um objeto AudioConfig. Esse objeto AudioConfig representa um fluxo de áudio. Você usará vários objetos AudioConfig desses durante as tarefas a seguir.

Verificação dependente do texto

A Verificação do Locutor é o ato de confirmar que um locutor corresponde a uma voz conhecida ou registrada. A primeira etapa é registrar um perfil de voz para que o serviço tenha algo com que comparar as futuras amostras de voz. Neste exemplo, você registra o perfil usando uma estratégia dependente do texto, que requer uma frase secreta específica a ser usada para o registro e a verificação. Confira os documentos de referência para obter uma lista de frases secretas compatíveis.

Função TextDependentVerification

Comece criando a função TextDependentVerification.

async function TextDependentVerification(client, speech_config)
{
    console.log ("Text Dependent Verification:\n");
    var profile = null;
    try {
        const type = sdk.VoiceProfileType.TextDependentVerification;
        // Create the profile.
        profile = await client.createProfileAsync(type, profile_locale);
        console.log ("Created profile ID: " + profile.profileId);
        // Get the activation phrases
        await GetActivationPhrases(type, profile_locale);
        await AddEnrollmentsToTextDependentProfile(client, profile, passphrase_files);
        const audio_config = GetAudioConfigFromFile(verify_file);
        const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
        await SpeakerVerify(profile, recognizer);
    }
    catch (error) {
        console.log ("Error:\n" + error);
    }
    finally {
        if (profile !== null) {
            console.log ("Deleting profile ID: " + profile.profileId);
            const deleteResult = await client.deleteProfileAsync (profile);
        }
    }
}

Essa função cria um objeto VoiceProfile com o método VoiceProfileClient.createProfileAsync. Há três tipos de VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

Nesse caso, passe VoiceProfileType.TextDependentVerification para VoiceProfileClient.createProfileAsync.

Em seguida, chame duas funções auxiliares que você definirá a seguir, AddEnrollmentsToTextDependentProfile e SpeakerVerify. Por fim, chame VoiceProfileClient.deleteProfileAsync para remover o perfil.

Função AddEnrollmentsToTextDependentProfile

Defina a função a seguir para registrar um perfil de voz:

async function AddEnrollmentsToTextDependentProfile(client, profile, audio_files)
{
    try {
        for (const file of audio_files) {
            console.log ("Adding enrollment to text dependent profile...");
            const audio_config = GetAudioConfigFromFile(file);
            const result = await client.enrollProfileAsync(profile, audio_config);
            if (result.reason === sdk.ResultReason.Canceled) {
                throw(JSON.stringify(sdk.VoiceProfileEnrollmentCancellationDetails.fromResult(result)));
            }
            else {
                console.log ("Remaining enrollments needed: " + result.privDetails["remainingEnrollmentsCount"] + ".");
            }
        };
        console.log ("Enrollment completed.\n");
    } catch (error) {
        console.log ("Error adding enrollments: " + error);
    }
}

Nessa função, você chamará a função GetAudioConfigFromFile definida anteriormente para criar objetos AudioConfig com base em amostras de áudio. Esses exemplos de áudio contêm uma frase secreta como "Minha voz é meu passaporte, verifique-me". Em seguida, você registra esses exemplos de áudio usando o método VoiceProfileClient.enrollProfileAsync.

Função SpeakerVerify

Defina SpeakerVerify da seguinte maneira:

async function SpeakerVerify(profile, recognizer)
{
    try {
        const model = sdk.SpeakerVerificationModel.fromProfile(profile);
        const result = await recognizer.recognizeOnceAsync(model);
        console.log ("Verified voice profile for speaker: " + result.profileId + ". Score is: " + result.score + ".\n");
    } catch (error) {
        console.log ("Error verifying speaker: " + error);
    }
}

Nesta função, você criará um objeto SpeakerVerificationModel com o método SpeakerVerificationModel.FromProfile, passando o objeto VoiceProfile criado anteriormente.

Em seguida, chame o método SpeechRecognizer.recognizeOnceAsync para validar uma amostra de áudio que contém a mesma frase secreta que as amostras de áudio que você registrou anteriormente. SpeechRecognizer.recognizeOnceAsync retorna um objeto SpeakerRecognitionResult, cuja propriedade score contém uma pontuação de similaridade que varia de 0,0 a 1,0. O objeto SpeakerRecognitionResult também contém uma propriedade reason do tipo ResultReason. Se a verificação tiver sido bem-sucedida, a propriedade reason deverá ter o valor RecognizedSpeaker.

Verificação independente do texto

Em contraste com a verificação dependente do texto, a verificação independente do texto:

  • Não requer que uma determinada frase secreta seja falada. Qualquer coisa pode ser falada.
  • Não exige três amostras de áudio, mas exige 20 segundos de áudio total.

Função TextIndependentVerification

Comece criando a função TextIndependentVerification.

async function TextIndependentVerification(client, speech_config)
{
    console.log ("Text Independent Verification:\n");
    var profile = null;
    try {
        const type = sdk.VoiceProfileType.TextIndependentVerification;
        // Create the profile.
        profile = await client.createProfileAsync(type, profile_locale);
        console.log ("Created profile ID: " + profile.profileId);
        // Get the activation phrases
        await GetActivationPhrases(type, profile_locale);
        await AddEnrollmentsToTextIndependentProfile(client, profile, [identify_file]);
        const audio_config = GetAudioConfigFromFile(passphrase_files[0]);
        const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
        await SpeakerVerify(profile, recognizer);
    }
    catch (error) {
        console.log ("Error:\n" + error);
    }
    finally {
        if (profile !== null) {
            console.log ("Deleting profile ID: " + profile.profileId);
            const deleteResult = await client.deleteProfileAsync (profile);
        }
    }
}

Como a função TextDependentVerification, essa função cria um objeto VoiceProfile com o método VoiceProfileClient.createProfileAsync.

Nesse caso, passe VoiceProfileType.TextIndependentVerification para createProfileAsync.

Em seguida, chame duas funções auxiliares: AddEnrollmentsToTextIndependentProfile, que você definirá a seguir, e SpeakerVerify, que você já definiu. Por fim, chame VoiceProfileClient.deleteProfileAsync para remover o perfil.

AddEnrollmentsToTextIndependentProfile

Defina a função a seguir para registrar um perfil de voz:

async function AddEnrollmentsToTextIndependentProfile(client, profile, audio_files)
{
    try {
        for (const file of audio_files) {
            console.log ("Adding enrollment to text independent profile...");
            const audio_config = GetAudioConfigFromFile(file);
            const result = await client.enrollProfileAsync (profile, audio_config);
            if (result.reason === sdk.ResultReason.Canceled) {
                throw(JSON.stringify(sdk.VoiceProfileEnrollmentCancellationDetails.fromResult(result)));
            }
            else {
                console.log ("Remaining audio time needed: " + (result.privDetails["remainingEnrollmentsSpeechLength"] / ticks_per_second) + " seconds.");
            }
        }
        console.log ("Enrollment completed.\n");
    } catch (error) {
        console.log ("Error adding enrollments: " + error);
    }
}

Nessa função, você chamará a função GetAudioConfigFromFile definida anteriormente para criar objetos AudioConfig com base em amostras de áudio. Em seguida, registre essas amostras de áudio usando o método VoiceProfileClient.enrollProfileAsync.

Identificação do locutor

A Identificação do Locutor é usada para determinar quem está falando dentre um determinado grupo de vozes registradas. O processo é semelhante à verificação independente de texto. A principal diferença é a capacidade de verificar vários perfis de voz ao mesmo tempo em vez de verificar em relação a um único perfil.

Função TextIndependentIdentification

Comece criando a função TextIndependentIdentification.

async function TextIndependentIdentification(client, speech_config)
{
    console.log ("Text Independent Identification:\n");
    var profile = null;
    try {
        const type = sdk.VoiceProfileType.TextIndependentIdentification;
        // Create the profile.
        profile = await client.createProfileAsync(type, profile_locale);
        console.log ("Created profile ID: " + profile.profileId);
        // Get the activation phrases
        await GetActivationPhrases(type, profile_locale);
        await AddEnrollmentsToTextIndependentProfile(client, profile, [identify_file]);
        const audio_config = GetAudioConfigFromFile(passphrase_files[0]);
        const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
        await SpeakerIdentify(profile, recognizer);
    }
    catch (error) {
        console.log ("Error:\n" + error);
    }
    finally {
        if (profile !== null) {
            console.log ("Deleting profile ID: " + profile.profileId);
            const deleteResult = await client.deleteProfileAsync (profile);
        }
    }
}

Como as funções TextDependentVerification e TextIndependentVerification, essa função cria um objeto VoiceProfile com o método VoiceProfileClient.createProfileAsync.

Nesse caso, passe VoiceProfileType.TextIndependentIdentification para VoiceProfileClient.createProfileAsync.

Em seguida, chame duas funções auxiliares: AddEnrollmentsToTextIndependentProfile, que você já definiu, e SpeakerIdentify, que você definirá em seguida. Por fim, chame VoiceProfileClient.deleteProfileAsync para remover o perfil.

Função SpeakerIdentify

Defina a função SpeakerIdentify conforme descrito a seguir:

async function SpeakerIdentify(profile, recognizer)
{
    try {
        const model = sdk.SpeakerIdentificationModel.fromProfiles([profile]);
        const result = await recognizer.recognizeOnceAsync(model);
        console.log ("The most similar voice profile is: " + result.profileId + " with similarity score: " + result.score + ".\n");
    } catch (error) {
        console.log ("Error identifying speaker: " + error);
    }
}

Nesta função, você criará um objeto SpeakerIdentificationModel com o método SpeakerIdentificationModel.fromProfiles, passando o objeto VoiceProfile criado anteriormente.

Em seguida, chame o método SpeechRecognizer.recognizeOnceAsync e transmita um exemplo de áudio. SpeechRecognizer.recognizeOnceAsync tenta identificar a voz desta amostra de áudio com base nos objetos VoiceProfile usados para criar o SpeakerIdentificationModel. Ele retorna um objeto SpeakerRecognitionResult, cuja propriedade profileId identifica o VoiceProfile correspondente, se houver, enquanto a propriedade score contém uma pontuação de similaridade que varia de 0,0 a 1,0.

Função principal

Por fim, defina a função main conforme descrito a seguir:

async function main() {
    const speech_config = sdk.SpeechConfig.fromSubscription(subscription_key, region);
    const client = new sdk.VoiceProfileClient(speech_config);

    await TextDependentVerification(client, speech_config);
    await TextIndependentVerification(client, speech_config);
    await TextIndependentIdentification(client, speech_config);
    console.log ("End of quickstart.");
}
main();

Essa função cria um objeto VoiceProfileClient, usado para criar, registrar e excluir perfis de voz. Ela chama as funções que você definiu anteriormente.

Documentação de referênciaPacotes (Download)Exemplos adicionais no GitHub

O SDK de Fala para Objective-C não dá suporte ao reconhecimento de locutor. Selecione outra linguagem de programação ou a referência do Objective-C e exemplos vinculados no início deste artigo.

Documentação de referênciaPacotes (Download)Exemplos adicionais no GitHub

O SDK de Fala para Swift não dá suporte ao reconhecimento de locutor. Selecione outra linguagem de programação ou a referência do Swift e exemplos vinculados no início deste artigo.

Documentação de referênciaPacotes (PyPi)Exemplos adicionais no GitHub

O SDK de Fala para Python não dá suporte ao reconhecimento de locutor. Selecione outra linguagem de programação ou a referência do Python e exemplos vinculados no início deste artigo.

Referência da API REST de conversão de fala em texto | Referência da API REST de conversão de fala em texto para áudios curtos | Exemplos adicionais no GitHub

Neste início rápido, você aprenderá os padrões de design básicos para reconhecimento de locutor usando o SDK de Fala, incluindo:

  • Verificação dependente do texto e independente do texto.
  • Identificação de locutor para identificar uma amostra de voz em meio a um grupo de vozes.
  • Exclusão de perfis de voz.

Para ter uma visão de alto nível dos conceitos de reconhecimento de locutor, confira o artigo de Visão geral. Consulte o nó Referência na barra de navegação esquerda para obter uma lista das plataformas com suporte.

Importante

A Microsoft limita o acesso ao reconhecimento de locutor. Inscreva-se para usá-los no formulário de Revisão do Acesso Limitado do Reconhecimento de Locutor dos Serviços de IA do Azure. Após a aprovação, você pode acessar as APIs de Reconhecimento do Locutor.

Pré-requisitos

Verificação dependente do texto

A Verificação do Locutor é o ato de confirmar que um locutor corresponde a uma voz conhecida ou registrada. A primeira etapa é registrar um perfil de voz para que o serviço tenha algo com que comparar as futuras amostras de voz. Neste exemplo, você registra o perfil usando uma estratégia dependente do texto, que requer uma frase secreta específica a ser usada para o registro e a verificação. Confira os documentos de referência para obter uma lista de frases secretas compatíveis.

Comece criando um perfil de voz. Você precisará inserir a região e a chave de assinatura do serviço de Fala para cada um dos comandos cURL deste artigo.

Importante

Lembre-se de remover a chave do seu código quando terminar e nunca poste-a publicamente. Para produção, use uma maneira segura de armazenar e acessar suas credenciais, como o Azure Key Vault. Consulte o artigo sobre segurança do serviços de IA do Azure para obter mais informações.

# Note Change locale if needed.
curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-dependent/profiles?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: application/json' \
--data-raw '{
    '\''locale'\'':'\''en-us'\''
}'

Há três tipos de perfil de voz:

  • Verificação dependente do texto
  • Verificação independente do texto
  • Identificação independente do texto

Nesse caso, você criará um perfil de voz de verificação dependente de texto. Você deve receber a resposta a seguir:

{
    "remainingEnrollmentsCount": 3,
    "locale": "en-us",
    "createdDateTime": "2020-09-29T14:54:29.683Z",
    "enrollmentStatus": "Enrolling",
    "modelVersion": null,
    "profileId": "714ce523-de76-4220-b93f-7c1cc1882d6e",
    "lastUpdatedDateTime": null,
    "enrollmentsCount": 0,
    "enrollmentsLength": 0.0,
    "enrollmentSpeechLength": 0.0
}

Em seguida, registre o perfil de voz. Para o valor do parâmetro --data-binary, especifique um arquivo de áudio no computador que contenha uma das frases secretas com suporte, como "Minha voz é meu passaporte, verifique-me". Você pode gravar um arquivo de áudio com um aplicativo, como o Gravador de Voz do Windows. Ou você pode gerá-lo usando a conversão de texto em fala.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-dependent/profiles/INSERT_PROFILE_ID_HERE/enrollments?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Você deve receber a resposta a seguir:

{
    "remainingEnrollmentsCount": 2,
    "passPhrase": "my voice is my passport verify me",
    "profileId": "714ce523-de76-4220-b93f-7c1cc1882d6e",
    "enrollmentStatus": "Enrolling",
    "enrollmentsCount": 1,
    "enrollmentsLength": 3.5,
    "enrollmentsSpeechLength": 2.88,
    "audioLength": 3.5,
    "audioSpeechLength": 2.88
}

Essa resposta informa que você precisa registrar mais dois amostras de áudio.

Depois de ter registrado um total de três amostras de áudio, você deverá receber a resposta a seguir:

{
    "remainingEnrollmentsCount": 0,
    "passPhrase": "my voice is my passport verify me",
    "profileId": "714ce523-de76-4220-b93f-7c1cc1882d6e",
    "enrollmentStatus": "Enrolled",
    "enrollmentsCount": 3,
    "enrollmentsLength": 10.5,
    "enrollmentsSpeechLength": 8.64,
    "audioLength": 3.5,
    "audioSpeechLength": 2.88
}

Agora você está pronto para verificar um exemplo de áudio em relação ao perfil de voz. Este exemplo de áudio deve conter a mesma frase secreta que os exemplos que você usou para registrar o perfil de voz.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-dependent/profiles/INSERT_PROFILE_ID_HERE:verify?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Você deve receber a resposta a seguir:

{
    "recognitionResult": "Accept",
    "score": 1.0
}

O Accept significa que a frase secreta coincidiu e que a verificação foi bem-sucedida. A resposta também contém uma pontuação de similaridade que varia de 0,0 a 1,0.

Para concluir, exclua o perfil de voz.

curl --location --request DELETE \
'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-dependent/profiles/INSERT_PROFILE_ID_HERE?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE'

Não há resposta.

Verificação independente do texto

Em contraste com a verificação dependente do texto, a verificação independente do texto:

  • Não requer que uma determinada frase secreta seja falada. Qualquer coisa pode ser falada.
  • Não exige três amostras de áudio, mas exige 20 segundos de áudio total.

Comece criando um perfil de verificação independente de texto.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-independent/profiles?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: application/json' \
--data-raw '{
    '\''locale'\'':'\''en-us'\''
}'

Você deve receber a resposta a seguir:

{
    "profileStatus": "Inactive",
    "remainingEnrollmentsSpeechLength": 20.0,
    "profileId": "3f85dca9-ffc9-4011-bf21-37fad2beb4d2",
    "locale": "en-us",
    "enrollmentStatus": "Enrolling",
    "createdDateTime": "2020-09-29T16:08:52.409Z",
    "lastUpdatedDateTime": null,
    "enrollmentsCount": 0,
    "enrollmentsLength": 0.0,
    "enrollmentSpeechLength": 0.0
    "modelVersion": null,
}

Em seguida, registre o perfil de voz. Novamente, em vez de enviar três amostras de áudio, você precisa enviar amostras de áudio que contenham um total de 20 segundos de áudio.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-independent/profiles/INSERT_PROFILE_ID_HERE/enrollments?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Depois de ter enviado amostras de áudio suficientes, você deverá receber a resposta a seguir:

{
    "remainingEnrollmentsSpeechLength": 0.0,
    "profileId": "3f85dca9-ffc9-4011-bf21-37fad2beb4d2",
    "enrollmentStatus": "Enrolled",
    "enrollmentsCount": 1,
    "enrollmentsLength": 33.16,
    "enrollmentsSpeechLength": 29.21,
    "audioLength": 33.16,
    "audioSpeechLength": 29.21
}

Agora você está pronto para verificar um exemplo de áudio em relação ao perfil de voz. Novamente, esta amostra de áudio não precisa conter uma frase secreta. Ela pode conter qualquer fala, mas deverá conter um total de pelo menos quatro segundos de áudio.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-independent/profiles/INSERT_PROFILE_ID_HERE:verify?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Você deve receber a resposta a seguir:

{
    "recognitionResult": "Accept",
    "score": 0.9196669459342957
}

O Accept significa que a verificação foi bem-sucedida. A resposta também contém uma pontuação de similaridade que varia de 0,0 a 1,0.

Para concluir, exclua o perfil de voz.

curl --location --request DELETE 'INSERT_ENDPOINT_HERE/speaker-recognition/verification/text-independent/profiles/INSERT_PROFILE_ID_HERE?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE'

Não há resposta.

Identificação do locutor

A Identificação do Locutor é usada para determinar quem está falando dentre um determinado grupo de vozes registradas. O processo é semelhante à verificação independente de texto. A principal diferença é a capacidade de verificar vários perfis de voz ao mesmo tempo em vez de verificar em relação a um único perfil.

Comece criando um perfil de identificação independente de texto.

# Note Change locale if needed.
curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/identification/text-independent/profiles?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: application/json' \
--data-raw '{
    '\''locale'\'':'\''en-us'\''
}'

Você deve receber a resposta a seguir:

{
    "profileStatus": "Inactive",
    "remainingEnrollmentsSpeechLengthInSec": 20.0,
    "profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
    "locale": "en-us",
    "enrollmentStatus": "Enrolling",
    "createdDateTime": "2020-09-22T17:25:48.642Z",
    "lastUpdatedDateTime": null,
    "enrollmentsCount": 0,
    "enrollmentsLengthInSec": 0.0,
    "enrollmentsSpeechLengthInSec": 0.0,
    "modelVersion": null
}

Em seguida, registre o perfil de voz. Novamente, você precisa enviar amostras de áudio que contenham um total de 20 segundos de áudio. Essas amostras não precisam conter uma frase secreta.

curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/identification/text-independent/profiles/INSERT_PROFILE_ID_HERE/enrollments?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Depois de ter enviado amostras de áudio suficientes, você deverá receber a resposta a seguir:

{
    "remainingEnrollmentsSpeechLength": 0.0,
    "profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
    "enrollmentStatus": "Enrolled",
    "enrollmentsCount": 2,
    "enrollmentsLength": 36.69,
    "enrollmentsSpeechLength": 31.95,
    "audioLength": 33.16,
    "audioSpeechLength": 29.21
}

Agora você está pronto para identificar uma amostra de áudio usando o perfil de voz. O comando Identify aceita uma lista delimitada por vírgula de possíveis IDs de perfil de voz. Neste caso, você só precisará passar a ID do perfil de voz criado anteriormente. Se desejar, você poderá passar várias IDs de perfil de voz, em que cada perfil de voz é registrado com amostras de áudio de uma voz diferente.

# Profile ids comma seperated list
curl --location --request POST 'INSERT_ENDPOINT_HERE/speaker-recognition/identification/text-independent/profiles:identifySingleSpeaker?api-version=2021-09-05&profileIds=INSERT_PROFILE_ID_HERE' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE' \
--header 'Content-Type: audio/wav' \
--data-binary @'INSERT_FILE_PATH_HERE'

Você deve receber a resposta a seguir:

Success:
{
    "identifiedProfile": {
        "profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
        "score": 0.9083486
    },
    "profilesRanking": [
        {
            "profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
            "score": 0.9083486
        }
    ]
}

A resposta contém a ID do perfil de voz que mais corresponde à amostra de áudio enviada. Ela também contém uma lista de perfis de voz qualificados, classificados em ordem de similaridade.

Para concluir, exclua o perfil de voz.

curl --location --request DELETE \
'INSERT_ENDPOINT_HERE/speaker-recognition/identification/text-independent/profiles/INSERT_PROFILE_ID_HERE?api-version=2021-09-05' \
--header 'Ocp-Apim-Subscription-Key: INSERT_SUBSCRIPTION_KEY_HERE'

Não há resposta.

A CLI de Fala dá suporte ao reconhecimento de locutor, mas ainda não incluímos um guia aqui. Selecione outra linguagem de programação para começar e saber mais sobre os conceitos.

Próximas etapas