Inicio rápido: Reconocimiento y comprobación de quién habla

Documentación de referenciaPaquete (NuGet)Ejemplos adicionales en GitHub

En este inicio rápido, aprenderá los patrones de diseño básicos del reconocimiento del hablante mediante el SDK de Voz, que incluyen:

  • Comprobación dependiente e independiente del texto.
  • Identificación del hablante para identificar una muestra de voz entre un grupo de voces.
  • Eliminación de perfiles de voz.

Para obtener una visión general de los conceptos de reconocimiento del hablante, consulte el artículo de información general. Consulte el nodo de referencia situado en el panel izquierdo para ver una lista de las plataformas admitidas.

Importante

Microsoft limita el acceso a Speaker Recognition. Aplicar para usarlo a través del formulario de revisión de acceso limitado Azure AI Speaker Recognition. Después de la aprobación, podrá acceder a las API de Speaker Recognition.

Requisitos previos

Instalación de Speech SDK

Antes de empezar, debe instalar el SDK de Voz. Utilice las siguientes instrucciones en función de la plataforma:

Dependencias de importación

Para ejecutar los ejemplos de este artículo, incluya las siguientes instrucciones de using al principio del script:

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

Creación de una configuración de voz

Para llamar al servicio Voz con el SDK de Voz, debe crear una instancia de SpeechConfig. En este ejemplo, se crea una instancia de SpeechConfig mediante una clave de suscripción y una región. Cree también código reutilizable básico para usarlo en el resto del artículo y que modificará cuando realice distintas personalizaciones.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Consulte el artículo Seguridad de servicios de Azure AI para más información.

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

Comprobación dependiente del texto

La verificación del hablante es el acto de confirmar que un hablante coincide con una voz conocida o inscrita. El primer paso es inscribir un perfil de voz, de modo que el servicio tenga algo para comparar futuras muestras de voz. En este ejemplo, el perfil se inscribe mediante una estrategia dependiente del texto que requiere que se use una frase de contraseña específica para la inscripción y la comprobación. Consulte los documentos de referencia para ver la lista de las frases de contraseña admitidas.

Empiece por crear la siguiente función en la clase Program para inscribir un 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}");
            }
        }
    }
}

En esta función, await client.CreateProfileAsync() es lo que crea realmente el nuevo perfil de voz. Una vez creada, debe especificar cómo va a introducir las muestras de audio. En este ejemplo, se usa AudioConfig.FromDefaultMicrophoneInput() para capturar audio del dispositivo de entrada predeterminado. A continuación, debe inscribir muestras de audio en un bucle while que realice un seguimiento del número de muestras restantes y necesarias para la inscripción. En cada iteración, client.EnrollProfileAsync(profile, audioInput) le pide que diga la frase de contraseña por el micrófono, y la muestra se agrega al perfil de voz.

Una vez completada la inscripción, llame a await SpeakerVerify(config, profile, profileMapping) para comprobarla con el perfil que acaba de crear. Agregue otra función 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}");
}

En esta función, se pasa el objeto VoiceProfile que acaba de crear para inicializar un modelo con el que realizar la comprobación. A continuación, await speakerRecognizer.RecognizeOnceAsync(model) le pide que vuelva a decir la frase de contraseña. Esta vez la valida con el perfil de voz y devuelve una puntuación de similitud comprendida entre 0,0 y 1,0. El objeto result también devuelve Accept o Reject, en función de si la frase de contraseña coincide.

A continuación, modifique la función Main() para llamar a las nuevas funciones que ha creado. Además, tenga en cuenta que crea un objeto Dictionary<string, string> para pasar por referencia en las llamadas de función. El motivo es que el servicio no permite almacenar un nombre legible con un objeto VoiceProfile creado y solo almacena un número de identificación con fines de privacidad. En la función VerificationEnroll, agrega a este diccionario una entrada con el identificador recién creado, junto con un nombre de texto. En escenarios de desarrollo de aplicaciones en los que es necesario mostrar un nombre legible, debe almacenar esta asignación en algún lugar, ya que el servicio no puede almacenarla.

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

Ejecute el script. Se le pedirá que diga la frase "My voice is my passport, verify me" (Mi voz es mi pasaporte, verifícame) tres veces para la inscripción y una vez más para la comprobación. El resultado devuelto es la puntuación de similitud, que puede usar para crear sus propios umbrales personalizados para la comprobación.

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

Comprobación independiente del texto

A diferencia de la comprobación dependiente del texto, la comprobación independiente del texto no requiere tres muestras de audio, pero requiere 20 segundos de audio total.

Realice un par de cambios sencillos en la función VerificationEnroll para cambiar a la comprobación independiente del texto. En primer lugar, cambie el tipo de comprobación a VoiceProfileType.TextIndependentVerification. A continuación, cambie el bucle while para realizar un seguimiento de result.RemainingEnrollmentsSpeechLength, que le seguirá solicitando que hable hasta que se hayan capturado 20 segundos de audio.

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

Vuelva a ejecutar el programa y se devolverá la puntuación de similitud.

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

Identificación del hablante

La identificación del hablante se utiliza para determinar quién está hablando de un grupo determinado de voces inscritas. El proceso es similar a la comprobación independiente del texto. La principal diferencia es la capacidad de comprobar varios perfiles de voz a la vez en lugar de comprobar un único perfil.

Cree una función IdentificationEnroll para inscribir varios perfiles de voz. El proceso de inscripción de cada perfil es el mismo que el proceso de inscripción de comprobación independiente del texto. El proceso requiere 20 segundos de audio para cada perfil. Esta función acepta una lista de cadenas profileNames y creará un nuevo perfil de voz para cada nombre de la lista. La función devuelve una lista de objetos VoiceProfile, que se usan en la siguiente función para identificar a un hablante.

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

Cree la siguiente función SpeakerIdentification para enviar una solicitud de identificación. La diferencia principal de esta función con respecto a una solicitud de verificación del hablante es el uso de SpeakerIdentificationModel.FromProfiles(), que acepta una 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}");
}

Cambie la función Main() por lo siguiente. Se crea una lista de cadenas profileNames, que debe pasar a la función IdentificationEnroll(). Se le pedirá que cree un nuevo perfil de voz para cada nombre de la lista, de modo que puede agregar más nombres para crear más perfiles para amigos o compañeros.

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

Ejecute el script. Se le pedirá que hable para inscribir las muestras de voz para el primer perfil. Una vez completada la inscripción, se le pedirá que repita este proceso para cada nombre de la lista profileNames. Una vez finalizada cada inscripción, se le pedirá que cualquier persona hable. A continuación, el servicio intenta identificar a esta persona entre los perfiles de voz inscritos.

Este ejemplo devuelve solo la coincidencia más cercana y su puntuación de similitud. Para obtener la respuesta completa que incluye las cinco mejores puntuaciones de similitud, agregue string json = result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult) a la función SpeakerIdentification.

Cambio del tipo de entrada de audio

En los ejemplos de este artículo se usa el micrófono del dispositivo predeterminado como entrada para las muestras de audio. En escenarios en los que es necesario usar archivos de audio en lugar de entradas de micrófono, cambie cualquier instancia de AudioConfig.FromDefaultMicrophoneInput() a AudioConfig.FromWavFileInput(path/to/your/file.wav) para cambiar a una entrada de archivo. También puede tener entradas mixtas, si usa un micrófono para la inscripción y archivos para la comprobación, por ejemplo.

Eliminación de inscripciones de perfiles de voz

Para eliminar un perfil inscrito, utilice la función DeleteProfileAsync() en el objeto VoiceProfileClient. En la función de ejemplo siguiente se muestra cómo eliminar un perfil de voz de un identificador de perfil de voz conocido:

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

Documentación de referenciaPaquete (NuGet)Ejemplos adicionales en GitHub

En este inicio rápido, aprenderá los patrones de diseño básicos del reconocimiento del hablante mediante el SDK de Voz, que incluyen:

  • Comprobación dependiente e independiente del texto.
  • Identificación del hablante para identificar una muestra de voz entre un grupo de voces.
  • Eliminación de perfiles de voz.

Para obtener una visión general de los conceptos de reconocimiento del hablante, consulte el artículo de información general. Consulte el nodo de referencia situado en el panel izquierdo para ver una lista de las plataformas admitidas.

Importante

Microsoft limita el acceso a Speaker Recognition. Aplicar para usarlo a través del formulario de revisión de acceso limitado Azure AI Speaker Recognition. Después de la aprobación, podrá acceder a las API de Speaker Recognition.

Requisitos previos

Instalación de Speech SDK

Antes de empezar, debe instalar el SDK de Voz. Utilice las siguientes instrucciones en función de la plataforma:

Dependencias de importación

Para ejecutar los ejemplos de este artículo, agregue las siguientes instrucciones al principio del archivo .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;

Creación de una configuración de voz

Para llamar al servicio Voz con el SDK de Voz, cree una clase SpeechConfig. Esta clase incluye información sobre la suscripción, como la clave, la región asociada, el punto de conexión, el host o el token de autorización.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Consulte el artículo Seguridad de servicios de Azure AI para más información.

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

Comprobación dependiente del texto

La verificación del hablante es el acto de confirmar que un hablante coincide con una voz conocida o inscrita. El primer paso es inscribir un perfil de voz, de modo que el servicio tenga algo para comparar futuras muestras de voz. En este ejemplo, el perfil se inscribe mediante una estrategia dependiente del texto que requiere que se use una frase de contraseña específica para la inscripción y la comprobación. Consulte los documentos de referencia para ver la lista de las frases de contraseña admitidas.

Función TextDependentVerification

Empiece por crear la función 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);
}

Esta función crea un objeto VoiceProfile con el método CreateProfileAsync. Existen tres tipos de VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

En este caso, pasará VoiceProfileType::TextDependentVerification a CreateProfileAsync.

Luego, llamará a dos funciones auxiliares que definirá a continuación: AddEnrollmentsToTextDependentProfile y SpeakerVerify. Por último, llame a DeleteProfileAsync para limpiar el perfil.

Función AddEnrollmentsToTextDependentProfile

Defina la función siguiente para inscribir un 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";
}

Luego, inscribirá muestras de audio en un bucle while que realiza un seguimiento del número de muestras restantes y necesarias para la inscripción. En cada iteración, EnrollProfileAsync le pide que diga la frase de contraseña por el micrófono, y la muestra se agrega al perfil de voz.

Función SpeakerVerify

Defina SpeakerVerify como se indica a continuación:

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

En esta función, creará un objeto SpeakerVerificationModel con el método SpeakerVerificationModel::FromProfile y pasará el objeto VoiceProfile que creó anteriormente.

Luego, SpeechRecognizer::RecognizeOnceAsync le pide que vuelva a decir la frase de contraseña. Esta vez la valida con el perfil de voz y devuelve una puntuación de similitud comprendida entre 0,0 y 1,0. El objeto SpeakerRecognitionResult también devuelve Accept o Reject, en función de si la frase de contraseña coincide.

Comprobación independiente del texto

A diferencia de la comprobación dependiente del texto, la comprobación independiente del texto no requiere tres muestras de audio, pero requiere 20 segundos de audio total.

Función TextIndependentVerification

Empiece por crear la función 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);
}

Al igual que la función TextDependentVerification, esta función crea un objeto VoiceProfile con el método CreateProfileAsync.

En este caso, pasará VoiceProfileType::TextIndependentVerification a CreateProfileAsync.

Luego, llamará a dos funciones auxiliares: AddEnrollmentsToTextIndependentProfile, que definirá a continuación y SpeakerVerify, que ya ha definido. Por último, llame a DeleteProfileAsync para limpiar el perfil.

AddEnrollmentsToTextIndependentProfile

Defina la función siguiente para inscribir un 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";
}

En esta función, inscribirá las muestras de audio en un bucle while que realiza un seguimiento del número de segundos de audio restantes y necesarios para la inscripción. En cada iteración, EnrollProfileAsync le pide que hable por el micrófono, y la muestra se agrega al perfil de voz.

Identificación del hablante

La identificación del hablante se utiliza para determinar quién está hablando de un grupo determinado de voces inscritas. El proceso es similar a la comprobación independiente del texto. La principal diferencia es la capacidad de comprobar varios perfiles de voz a la vez en lugar de comprobar un único perfil.

Función TextIndependentIdentification

Empiece por crear la función 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);
}

Al igual que las funciones TextDependentVerification y TextIndependentVerification, esta función crea un objeto VoiceProfile con el método CreateProfileAsync.

En este caso, pasará VoiceProfileType::TextIndependentIdentification a CreateProfileAsync.

Luego, llamará a dos funciones auxiliares: AddEnrollmentsToTextIndependentProfile, que ya ha definido y SpeakerIdentify, que definirá a continuación. Por último, llame a DeleteProfileAsync para limpiar el perfil.

Función SpeakerIdentify

Defina la función SpeakerIdentify de la siguiente manera:

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

En esta función, creará un objeto SpeakerIdentificationModel con el método SpeakerIdentificationModel:: FromProfiles. SpeakerIdentificationModel::FromProfiles acepta una lista de objetos VoiceProfile. En este caso, pasará el objeto VoiceProfile que creó anteriormente. Si lo desea, puede pasar varios objetos VoiceProfile, cada uno inscrito con muestras de audio de una voz diferente.

Luego, SpeechRecognizer::RecognizeOnceAsync le pide que hable de nuevo. Esta vez se compara su voz con los perfiles de voz inscritos y se devuelve el perfil de voz más parecido.

Función main

Por último, defina la función main de la siguiente manera:

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

Esta función llama a las funciones que definió anteriormente. Primero crea un objeto VoiceProfileClient y un objeto SpeakerRecognizer.

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

El objeto VoiceProfileClient se usa para crear, inscribir y eliminar perfiles de voz. El objeto SpeakerRecognizer se utiliza para validar muestras de voz con uno o varios perfiles de voz inscritos.

Cambio del tipo de entrada de audio

En los ejemplos de este artículo se usa el micrófono del dispositivo predeterminado como entrada para las muestras de audio. En escenarios en los que necesite usar archivos de audio en lugar de la entrada de micrófono, cambie la línea siguiente:

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

a:

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

También puede reemplazar el uso de audio_config por Audio::AudioConfig::FromWavFileInput. También puede tener entradas mixtas, si usa un micrófono para la inscripción y archivos para la comprobación, por ejemplo.

Documentación de referenciaPaquete (Go)Ejemplos adicionales en GitHub

En este inicio rápido, aprenderá los patrones de diseño básicos del reconocimiento del hablante mediante el SDK de Voz, que incluyen:

  • Comprobación dependiente e independiente del texto.
  • Identificación del hablante para identificar una muestra de voz entre un grupo de voces.
  • Eliminación de perfiles de voz.

Para obtener una visión general de los conceptos de reconocimiento del hablante, consulte el artículo de información general. Consulte el nodo de referencia situado en el panel izquierdo para ver una lista de las plataformas admitidas.

Importante

Microsoft limita el acceso a Speaker Recognition. Aplicar para usarlo a través del formulario de revisión de acceso limitado Azure AI Speaker Recognition. Después de la aprobación, podrá acceder a las API de Speaker Recognition.

Requisitos previos

Configuración del entorno

Instale el SDK de Voz para Go. Consulte la guía de instalación del SDK para conocer más requisitos.

Realización de una identificación independiente

Siga estos pasos para crear un nuevo módulo de GO.

  1. Abra un símbolo del sistema donde quiera el nuevo módulo y cree un archivo llamado independent-identification.go.

  2. Reemplace el contenido de independent-identification.go por el código siguiente.

    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. En independent-identification.go, reemplace YourSubscriptionKey por la clave de recurso de Voz y YourServiceRegion por la región del recurso de Voz.

    Importante

    Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Consulte el artículo Seguridad de servicios de Azure AI para más información.

Ejecute los siguientes comandos para crear un archivo go.mod que vincule a los componentes hospedados en GitHub:

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

Compile y ejecute ahora el código:

go build
go run independent-identification

Realización de una comprobación independiente

Siga estos pasos para crear un nuevo módulo de GO.

  1. Abra un símbolo del sistema donde quiera el nuevo módulo y cree un archivo llamado independent-verification.go.

  2. Reemplace el contenido de independent-verification.go por el código siguiente.

    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. En independent-verification.go, reemplace YourSubscriptionKey por la clave de recurso de Voz y YourServiceRegion por la región del recurso de Voz.

Ejecute los siguientes comandos para crear un archivo go.mod que vincule a los componentes hospedados en GitHub:

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

Compile y ejecute ahora el código:

go build
go run independent-verification

Limpieza de recursos

Puede usar Azure Portal o la Interfaz de la línea de comandos (CLI) de Azure para quitar el recurso de Voz que creó.

Documentación de referencia | Ejemplos adicionales en GitHub

El SDK de Voz para Java admite el reconocimiento del hablante, pero aún no hemos incluido una guía aquí. Seleccione otro lenguaje de programación para empezar a trabajar y conocer los conceptos, o consulte la referencia de Java y los ejemplos vinculados desde el principio de este artículo.

Documentación de referenciaPaquete (npm)Ejemplos adicionales en GitHubCódigo fuente de la biblioteca

En este inicio rápido, aprenderá los patrones de diseño básicos del reconocimiento del hablante mediante el SDK de Voz, que incluyen:

  • Comprobación dependiente e independiente del texto.
  • Identificación del hablante para identificar una muestra de voz entre un grupo de voces.
  • Eliminación de perfiles de voz.

Para obtener una visión general de los conceptos de reconocimiento del hablante, consulte el artículo de información general. Consulte el nodo de referencia situado en el panel izquierdo para ver una lista de las plataformas admitidas.

Importante

Microsoft limita el acceso a Speaker Recognition. Aplicar para usarlo a través del formulario de revisión de acceso limitado Azure AI Speaker Recognition. Después de la aprobación, podrá acceder a las API de Speaker Recognition.

Requisitos previos

Instalación de Speech SDK

Antes de empezar, debe instalar el SDK de Voz para JavaScript.

En función del entorno de destino, use una de las siguientes:

Descargue y extraiga el archivo microsoft.cognitiveservices.speech.sdk.bundle.js del SDK de Voz para JavaScript . Colóquelo en una carpeta accesible para el archivo HTML.

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

Sugerencia

Si el destino es un explorador web y usa la etiqueta <script>, el prefijo sdk no es necesario. El prefijo sdk es un alias que se usa para asignar un nombre al módulo require.

Dependencias de importación

Para ejecutar los ejemplos de este artículo, agregue las siguientes instrucciones al principio del archivo .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;

Estas instrucciones importan las bibliotecas necesarias y obtienen la clave y región de la suscripción del servicio Voz de las variables de entorno. También especifican las rutas de acceso a los archivos de audio que usará en las siguientes tareas.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Consulte el artículo Seguridad de servicios de Azure AI para más información.

Creación de una función auxiliar

Agregue la siguiente función auxiliar para leer archivos de audio en secuencias para su uso por parte del servicio Voz:

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

En esta función, se usan los métodos AudioInputStream. createPushStream y AudioConfig. fromStreamInput para crear un objeto AudioConfig. Este objeto AudioConfig representa una secuencia de audio. En las siguientes tareas, utilizará varios de estos objetos AudioConfig.

Comprobación dependiente del texto

La verificación del hablante es el acto de confirmar que un hablante coincide con una voz conocida o inscrita. El primer paso es inscribir un perfil de voz, de modo que el servicio tenga algo para comparar futuras muestras de voz. En este ejemplo, el perfil se inscribe mediante una estrategia dependiente del texto que requiere que se use una frase de contraseña específica para la inscripción y la comprobación. Consulte los documentos de referencia para ver la lista de las frases de contraseña admitidas.

Función TextDependentVerification

Empiece por crear la función 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);
        }
    }
}

Esta función crea un objeto VoiceProfile con el método VoiceProfileClient.createProfileAsync. Existen tres tipos de VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

En este caso, pasará VoiceProfileType.TextDependentVerification a VoiceProfileClient.createProfileAsync.

Luego, llamará a dos funciones auxiliares que definirá a continuación: AddEnrollmentsToTextDependentProfile y SpeakerVerify. Por último, llamará a VoiceProfileClient. deleteProfileAsync para quitar el perfil.

Función AddEnrollmentsToTextDependentProfile

Defina la función siguiente para inscribir un 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);
    }
}

En esta función, se llama a la función GetAudioConfigFromFile, que se ha definido anteriormente, para crear objetos AudioConfig a partir de muestras de audio. Estos ejemplos de audio contienen una frase de contraseña como "My voice is my passport, verify me" (Mi voz es mi pasaporte, verifícame). Después, debe inscribir estos ejemplos de audio mediante el método VoiceProfileClient.enrollProfileAsync.

Función SpeakerVerify

Defina SpeakerVerify como se indica a continuación:

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

En esta función, creará un objeto SpeakerVerificationModel con el método SpeakerVerificationModel.FromProfile y pasará el objeto VoiceProfile que creó anteriormente.

A continuación, llamará al método SpeechRecognizer. recognizeOnceAsync para validar una muestra de audio que contiene la misma frase de contraseña que las muestras de audio que inscribió anteriormente. SpeechRecognizer.recognizeOnceAsync devuelve un objeto SpeakerRecognitionResult cuya propiedad score contiene una puntuación de similitud comprendida entre 0,0 y 1,0. El objeto SpeakerRecognitionResult también contiene una propiedad reason del tipo ResultReason. Si la comprobación se realizó correctamente, la propiedad reason debería tener el valor RecognizedSpeaker.

Comprobación independiente del texto

A diferencia de la comprobación dependiente del texto, la comprobación independiente del texto:

  • No es necesario que se diga una frase de contraseña determinada. Se puede decir cualquier cosa.
  • No se necesitan tres muestras de audio, pero 20 segundos de audio en total.

Función TextIndependentVerification

Empiece por crear la función 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);
        }
    }
}

Al igual que la función TextDependentVerification, esta función crea un objeto VoiceProfile con el método VoiceProfileClient.createProfileAsync.

En este caso, pasará VoiceProfileType.TextIndependentVerification a createProfileAsync.

Luego, llamará a dos funciones auxiliares: AddEnrollmentsToTextIndependentProfile, que definirá a continuación, y SpeakerVerify, que ya ha definido. Por último, llamará a VoiceProfileClient. deleteProfileAsync para quitar el perfil.

AddEnrollmentsToTextIndependentProfile

Defina la función siguiente para inscribir un 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);
    }
}

En esta función, se llama a la función GetAudioConfigFromFile, que se ha definido anteriormente, para crear objetos AudioConfig a partir de muestras de audio. Luego, se inscriben estas muestras de audio mediante el método VoiceProfileClient. enrollProfileAsync.

Identificación del hablante

La identificación del hablante se utiliza para determinar quién está hablando de un grupo determinado de voces inscritas. El proceso es similar a la comprobación independiente del texto. La principal diferencia es la capacidad de comprobar varios perfiles de voz a la vez en lugar de comprobar un único perfil.

Función TextIndependentIdentification

Empiece por crear la función 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);
        }
    }
}

Al igual que las funciones TextDependentVerification y TextIndependentVerification, esta función crea un objeto VoiceProfile con el método VoiceProfileClient.createProfileAsync.

En este caso, pasará VoiceProfileType.TextIndependentIdentification a VoiceProfileClient.createProfileAsync.

Luego, llamará a dos funciones auxiliares: AddEnrollmentsToTextIndependentProfile, que ya ha definido y SpeakerIdentify, que definirá a continuación. Por último, llamará a VoiceProfileClient. deleteProfileAsync para quitar el perfil.

Función SpeakerIdentify

Defina la función SpeakerIdentify de la siguiente manera:

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

En esta función, creará un objeto SpeakerIdentificationModel con el método SpeakerIdentificationModel.fromProfiles y pasará el objeto VoiceProfile que creó anteriormente.

Luego, llamará al método SpeechRecognizer. recognizeOnceAsync y utilizara una muestra de audio. SpeechRecognizer.recognizeOnceAsync intentará identificar la voz de esta muestra de audio en función de los objetos VoiceProfile que se usaron para crear SpeakerIdentificationModel. Devolverá un objeto SpeakerRecognitionResult, cuya propiedad profileId identificará el VoiceProfile coincidente, si hay alguno, mientras que la propiedad score contendrá contiene una puntuación de similitud comprendida entre 0,0 y 1,0.

Función main

Por último, defina la función main de la siguiente manera:

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

Esta función crea un objeto VoiceProfileClient, que se usa para crear, inscribir y eliminar perfiles de voz. Y, posteriormente, llama a las funciones que definió anteriormente.

Documentación de referenciaPaquete (Download)Ejemplos adicionales en GitHub

El SDK de Voz para Objective-C no admite el reconocimiento del hablante. Seleccione otro lenguaje de programación o la referencia de Objective-C y los ejemplos vinculados desde el principio de este artículo.

Documentación de referenciaPaquete (Download)Ejemplos adicionales en GitHub

El SDK de Voz para Swift no admite el reconocimiento del hablante. Seleccione otro lenguaje de programación o la referencia de Swift y los ejemplos vinculados desde el principio de este artículo.

Documentación de referenciaPaquete (PyPi)Ejemplos adicionales en GitHub

El SDK de Voz para Python no admite el reconocimiento del hablante. Seleccione otro lenguaje de programación o la referencia de Python y los ejemplos vinculados desde el principio de este artículo.

Referencia de la API de REST en la conversión de voz en texto | Referencia de la API de REST en la conversión de voz en texto para audios breves | Ejemplos adicionales sobre GitHub

En este inicio rápido, aprenderá los patrones de diseño básicos del reconocimiento del hablante mediante el SDK de Voz, que incluyen:

  • Comprobación dependiente e independiente del texto.
  • Identificación del hablante para identificar una muestra de voz entre un grupo de voces.
  • Eliminación de perfiles de voz.

Para obtener una visión general de los conceptos de reconocimiento del hablante, consulte el artículo de información general. Consulte el nodo de referencia situado en el panel izquierdo para ver una lista de las plataformas admitidas.

Importante

Microsoft limita el acceso a Speaker Recognition. Aplicar para usarlo a través del formulario de revisión de acceso limitado Azure AI Speaker Recognition. Después de la aprobación, podrá acceder a las API de Speaker Recognition.

Requisitos previos

Comprobación dependiente del texto

La verificación del hablante es el acto de confirmar que un hablante coincide con una voz conocida o inscrita. El primer paso es inscribir un perfil de voz, de modo que el servicio tenga algo para comparar futuras muestras de voz. En este ejemplo, el perfil se inscribe mediante una estrategia dependiente del texto que requiere que se use una frase de contraseña específica para la inscripción y la comprobación. Consulte los documentos de referencia para ver la lista de las frases de contraseña admitidas.

Para empezar, cree un perfil de voz. Tendrá que insertar la región y la clave de suscripción del servicio Voz en cada uno de los comandos curl de este artículo.

Importante

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, use una forma segura de almacenar sus credenciales y acceder a ellas, como Azure Key Vault. Consulte el artículo Seguridad de servicios de Azure AI para más información.

# 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'\''
}'

Hay tres tipos de perfiles de voz:

  • Comprobación dependiente del texto
  • Comprobación independiente del texto
  • Identificación independiente del texto

En este caso, se crea un perfil de voz de comprobación dependiente del texto. Debe recibir la respuesta siguiente:

{
    "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
}

Luego, se inscribe el perfil de voz. Para el valor del parámetro --data-binary, especifique un archivo de audio en el equipo que contenga una de las frase de contraseña admitidas, como "My voice is my passport, verify me" (Mi voz es mi pasaporte, verifícame). Puede grabar un archivo de audio con una aplicación, como Windows Voice Recorder. O bien, puede generarlo mediante texto a voz.

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'

Debe recibir la respuesta siguiente:

{
    "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
}

Esta respuesta le indica que debe inscribir dos muestras de audio más.

Cuando inscriba un total de tres ejemplos de audio, debe recibir la siguiente respuesta:

{
    "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
}

Ya está listo para comprobar una muestra de audio con el perfil de voz. Esta muestra de audio debe contener la misma frase de contraseña que los ejemplos que usó para inscribir el 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'

Debe recibir la respuesta siguiente:

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

Accept significa que la frase de contraseña coincidía y que la comprobación se realizó correctamente. La respuesta también contiene una puntuación de similitud comprendida entre 0,0 y 1,0.

Para finalizar, elimine el 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'

No hay ninguna respuesta.

Comprobación independiente del texto

A diferencia de la comprobación dependiente del texto, la comprobación independiente del texto:

  • No es necesario que se diga una frase de contraseña determinada. Se puede decir cualquier cosa.
  • No se necesitan tres muestras de audio, pero 20 segundos de audio en total.

Para empezar, cree un perfil de comprobación independiente del 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'\''
}'

Debe recibir la respuesta siguiente:

{
    "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,
}

A continuación, inscriba el perfil de voz. De nuevo, en lugar de enviar tres muestras de audio, debe enviar ejemplos de audio que contengan un total de 20 segundos de audio.

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'

Una vez que haya enviado suficientes muestras de audio, debe recibir la siguiente respuesta:

{
    "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
}

Ya está listo para comprobar una muestra de audio con el perfil de voz. De nuevo, no es preciso que esta muestra contenga una frase de contraseña. Puede contener cualquier locución, pero debe contener un total de al menos cuatro segundos de audio.

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'

Debe recibir la respuesta siguiente:

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

Accept significa que la comprobación se realizó correctamente. La respuesta también contiene una puntuación de similitud comprendida entre 0,0 y 1,0.

Para finalizar, elimine el 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'

No hay ninguna respuesta.

Identificación del hablante

La identificación del hablante se utiliza para determinar quién está hablando de un grupo determinado de voces inscritas. El proceso es similar a la comprobación independiente del texto. La principal diferencia es la capacidad de comprobar varios perfiles de voz a la vez en lugar de comprobar un único perfil.

Para empezar, cree un perfil de identificación independiente del 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'\''
}'

Debe recibir la respuesta siguiente:

{
    "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
}

Luego, se inscribe el perfil de voz. De nuevo, debe enviar muestras de audio que contengan un total de 20 segundos de audio. No es necesario que estas muestras contengan una frase de contraseña.

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'

Una vez que haya enviado suficientes muestras de audio, debe recibir la siguiente respuesta:

{
    "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
}

Ya está listo para identificar una muestra de audio mediante el perfil de voz. El comando de identificación acepta una lista delimitada por comas de posibles identificadores del perfil de voz. En este caso, tendrá que pasar el identificador del perfil de voz que creó anteriormente. Si lo desea, puede pasar varios identificadores de perfil de voz, y cada perfil de voz se inscribe con muestras de audio de una 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'

Debe recibir la respuesta siguiente:

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

La respuesta contiene el identificador del perfil de voz que más se aproxime al ejemplo de audio que envió. También contiene una lista de perfiles de voz candidatos, clasificados por orden de similitud.

Para finalizar, elimine el 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'

No hay ninguna respuesta.

La CLI de Voz admite el reconocimiento del hablante, pero aún no hemos incluido una guía aquí. Seleccione otro lenguaje de programación para empezar a trabajar y conocer los conceptos.

Pasos siguientes

Consulte los ejemplos del inicio rápido en GitHub.