Snabbstart: Identifiera och verifiera vem som talar

Referensdokumentation | Paket (NuGet) | Ytterligare exempel på GitHub

I den här snabbstarten lär du dig grundläggande designmönster för talarigenkänning med hjälp av Speech SDK, inklusive:

  • Textberoende och textoberoende verifiering.
  • Talaridentifiering för att identifiera ett röstexempel bland en grupp röster.
  • Ta bort röstprofiler.

En översikt över begreppen för talarigenkänning finns i artikeln Översikt . En lista över plattformar som stöds finns i referensnoden i det vänstra fönstret.

Viktigt

Microsoft begränsar åtkomsten till talarigenkänning. Använd för att använda det via formuläret för granskning av begränsad åtkomst för Talarigenkänning i Azure AI . Efter godkännandet kan du komma åt API:erna för talarigenkänning.

Förutsättningar

Installera Speech SDK

Innan du börjar måste du installera Speech SDK. Använd följande instruktioner beroende på din plattform:

Importera beroenden

Om du vill köra exemplen i den här artikeln inkluderar du följande using instruktioner överst i skriptet:

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

Skapa en talkonfiguration

Om du vill anropa Speech-tjänsten med hjälp av Speech SDK måste du skapa en SpeechConfig instans. I det här exemplet skapar du en SpeechConfig instans med hjälp av en prenumerationsnyckel och region. Du kan också skapa grundläggande exempelkod som du kan använda för resten av den här artikeln, som du ändrar för olika anpassningar.

Viktigt

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln om Azure AI-tjänster.

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

Textberoende verifiering

Talarverifiering är att bekräfta att en talare matchar en känd eller registrerad röst. Det första steget är att registrera en röstprofil så att tjänsten har något att jämföra framtida röstexempel mot. I det här exemplet registrerar du profilen med hjälp av en textberoende strategi som kräver en specifik lösenfras som ska användas för registrering och verifiering. En lista över lösenfraser som stöds finns i referensdokumenten .

Börja med att skapa följande funktion i klassen Program för att registrera en röstprofil:

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

I den här funktionen await client.CreateProfileAsync() är det som faktiskt skapar den nya röstprofilen. När den har skapats anger du hur du ska mata in ljudexempel med hjälp AudioConfig.FromDefaultMicrophoneInput() av i det här exemplet för att spela in ljud från din standardindataenhet. Därefter registrerar du ljudexempel i en while loop som spårar antalet återstående prover och som krävs för registrering. I varje iteration client.EnrollProfileAsync(profile, audioInput) uppmanas du att tala upp lösenfrasen i mikrofonen och lägga till exemplet i röstprofilen.

När registreringen är klar anropar await SpeakerVerify(config, profile, profileMapping) du för att verifiera mot den profil som du nyss skapade. Lägg till en annan funktion för att definiera 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}");
}

I den här funktionen skickar du objektet VoiceProfile som du nyss skapade för att initiera en modell att verifiera mot. await speakerRecognizer.RecognizeOnceAsync(model) Sedan uppmanas du att tala om lösenfrasen igen. Den här gången valideras den mot din röstprofil och returnerar en likhetspoäng som sträcker sig från 0,0 till 1,0. Objektet result returnerar Accept också eller Reject, baserat på om lösenfrasen matchar.

Ändra sedan funktionen Main() så att den anropar de nya funktioner som du har skapat. Observera också att du skapar en Dictionary<string, string> för att skicka referens via dina funktionsanrop. Anledningen till detta är att tjänsten inte tillåter lagring av ett läsbart namn med ett skapat VoiceProfileoch endast lagrar ett ID-nummer i sekretesssyfte. VerificationEnroll I funktionen lägger du till en post med det nyligen skapade ID:t i den här ordlistan tillsammans med ett textnamn. I programutvecklingsscenarier där du behöver visa ett läsbart namn måste du lagra mappningen någonstans eftersom tjänsten inte kan lagra den.

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

Kör skriptet. Du uppmanas att tala frasen "Min röst är mitt pass, verifiera mig" tre gånger för registrering och en gång till för verifiering. Resultatet som returneras är likhetspoängen, som du kan använda för att skapa egna anpassade tröskelvärden för verifiering.

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

Textoberoende verifiering

Till skillnad från textberoende verifiering kräver textoberoende verifiering inte tre ljudexempel men kräver 20 sekunders totalt ljud.

Gör några enkla ändringar i funktionen VerificationEnroll för att växla till textoberoende verifiering. Först ändrar du verifieringstypen till VoiceProfileType.TextIndependentVerification. Ändra sedan loopen while för att spåra result.RemainingEnrollmentsSpeechLength, som fortsätter att uppmana dig att tala tills 20 sekunders ljud har avbildats.

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

Kör programmet igen och likhetspoängen returneras.

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

Talaridentifiering

Talaridentifiering används för att avgöra vem som talar från en viss grupp med registrerade röster. Processen liknar textoberoende verifiering. Den största skillnaden är möjligheten att verifiera mot flera röstprofiler samtidigt i stället för att verifiera mot en enda profil.

Skapa en funktion IdentificationEnroll för att registrera flera röstprofiler. Registreringsprocessen för varje profil är densamma som registreringsprocessen för textoberoende verifiering. Processen kräver 20 sekunders ljud för varje profil. Den här funktionen accepterar en lista med strängar profileNames och skapar en ny röstprofil för varje namn i listan. Funktionen returnerar en lista med VoiceProfile objekt som du använder i nästa funktion för att identifiera en talare.

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

Skapa följande funktion SpeakerIdentification för att skicka en identifieringsbegäran. Den största skillnaden i den här funktionen jämfört med en begäran om talarverifiering är användningen av SpeakerIdentificationModel.FromProfiles(), som accepterar en lista med VoiceProfile objekt.

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

Ändra funktionen Main() till följande. Du skapar en lista med strängar profileNamessom du skickar till din IdentificationEnroll() funktion. Du uppmanas att skapa en ny röstprofil för varje namn i den här listan, så att du kan lägga till fler namn för att skapa fler profiler för vänner eller kollegor.

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

Kör skriptet. Du uppmanas att tala för att registrera röstexempel för den första profilen. När registreringen är klar uppmanas du att upprepa den här processen för varje namn i profileNames listan. När varje registrering är klar uppmanas du att låta någon tala. Tjänsten försöker sedan identifiera den här personen bland dina registrerade röstprofiler.

Det här exemplet returnerar bara den närmaste matchningen och dess likhetspoäng. Om du vill få det fullständiga svaret som innehåller de fem främsta likhetspoängen lägger du till string json = result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult) i funktionen SpeakerIdentification .

Ändra ljudinmatningstyp

Exemplen i den här artikeln använder enhetens standardmikrofon som indata för ljudexempel. I scenarier där du behöver använda ljudfiler i stället för mikrofonindata ändrar du valfri instans av AudioConfig.FromDefaultMicrophoneInput() till för AudioConfig.FromWavFileInput(path/to/your/file.wav) att växla till en filinmatning. Du kan också ha blandade indata med hjälp av en mikrofon för registrering och filer för verifiering, till exempel.

Ta bort röstprofilregistreringar

Om du vill ta bort en registrerad profil använder du DeleteProfileAsync() funktionen på objektet VoiceProfileClient . Följande exempelfunktion visar hur du tar bort en röstprofil från ett känt röstprofil-ID:

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

Referensdokumentation | Paket (NuGet) | Ytterligare exempel på GitHub

I den här snabbstarten lär du dig grundläggande designmönster för talarigenkänning med hjälp av Speech SDK, inklusive:

  • Textberoende och textoberoende verifiering.
  • Talaridentifiering för att identifiera ett röstexempel bland en grupp röster.
  • Ta bort röstprofiler.

En översikt över begreppen för talarigenkänning finns i artikeln Översikt . En lista över plattformar som stöds finns i referensnoden i det vänstra fönstret.

Viktigt

Microsoft begränsar åtkomsten till talarigenkänning. Använd för att använda det via formuläret för granskning av begränsad åtkomst för Talarigenkänning i Azure AI . Efter godkännandet kan du komma åt API:erna för talarigenkänning.

Förutsättningar

Installera Speech SDK

Innan du börjar måste du installera Speech SDK. Använd följande instruktioner beroende på din plattform:

Importera beroenden

Om du vill köra exemplen i den här artikeln lägger du till följande -instruktioner överst i .cpp-filen:

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

Skapa en talkonfiguration

Om du vill anropa Speech-tjänsten med hjälp av Speech SDK skapar du en SpeechConfig klass. Den här klassen innehåller information om din prenumeration, till exempel din nyckel och tillhörande region, slutpunkt, värd eller auktoriseringstoken.

Viktigt

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln om Azure AI-tjänster.

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

Textberoende verifiering

Talarverifiering är att bekräfta att en talare matchar en känd eller registrerad röst. Det första steget är att registrera en röstprofil så att tjänsten har något att jämföra framtida röstexempel mot. I det här exemplet registrerar du profilen med hjälp av en textberoende strategi som kräver en specifik lösenfras som ska användas för registrering och verifiering. En lista över lösenfraser som stöds finns i referensdokumenten .

Funktionen TextDependentVerification

Börja med att skapa TextDependentVerification funktionen:

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

Den här funktionen skapar ett VoiceProfile-objekt med metoden CreateProfileAsync . Det finns tre typer av VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

I det här fallet skickar VoiceProfileType::TextDependentVerification du till CreateProfileAsync.

Sedan anropar du två hjälpfunktioner som du definierar härnäst, AddEnrollmentsToTextDependentProfile och SpeakerVerify. Anropa slutligen DeleteProfileAsync för att rensa profilen.

Funktionen AddEnrollmentsToTextDependentProfile

Definiera följande funktion för att registrera en röstprofil:

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

I den här funktionen registrerar du ljudexempel i en while loop som spårar antalet återstående exempel och som krävs för registrering. I varje iteration uppmanar EnrollProfileAsync dig att tala upp lösenfrasen i mikrofonen och lägger till exemplet i röstprofilen.

Funktionen SpeakerVerify

Definiera SpeakerVerify på följande sätt:

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

I den här funktionen skapar du ett SpeakerVerificationModel-objekt med metoden SpeakerVerificationModel::FromProfile och skickar in VoiceProfile-objektet som du skapade tidigare.

Sedan uppmanar SpeechRecognizer::RecognizeOnceAsync dig att tala upp lösenfrasen igen. Den här gången valideras den mot din röstprofil och returnerar en likhetspoäng som sträcker sig från 0,0 till 1,0. Objektet SpeakerRecognitionResult returnerar Accept eller Reject baseras också på om lösenfrasen matchar.

Textoberoende verifiering

Till skillnad från textberoende verifiering kräver textoberoende verifiering inte tre ljudexempel men kräver 20 sekunders totalt ljud.

Funktionen TextIndependentVerification

Börja med att skapa TextIndependentVerification funktionen:

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

Precis som funktionen skapar den TextDependentVerification här funktionen ett VoiceProfile-objekt med metoden CreateProfileAsync .

I det här fallet skickar VoiceProfileType::TextIndependentVerification du till CreateProfileAsync.

Sedan anropar du två hjälpfunktioner: AddEnrollmentsToTextIndependentProfile, som du definierar härnäst och SpeakerVerify, som du redan har definierat. Anropa slutligen DeleteProfileAsync för att rensa profilen.

AddEnrollmentsToTextIndependentProfile

Definiera följande funktion för att registrera en röstprofil:

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

I den här funktionen registrerar du ljudexempel i en while loop som spårar antalet sekunder av återstående ljud och som krävs för registrering. I varje iteration uppmanar EnrollProfileAsync dig att tala i mikrofonen och lägger till exemplet i röstprofilen.

Talaridentifiering

Talaridentifiering används för att avgöra vem som talar från en viss grupp med registrerade röster. Processen liknar textoberoende verifiering. Den största skillnaden är möjligheten att verifiera mot flera röstprofiler samtidigt i stället för att verifiera mot en enda profil.

TextIndependentIdentification-funktion

Börja med att skapa TextIndependentIdentification funktionen:

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

Precis som TextDependentVerification funktionerna och TextIndependentVerification skapar den här funktionen ett VoiceProfile-objekt med metoden CreateProfileAsync .

I det här fallet skickar VoiceProfileType::TextIndependentIdentification du till CreateProfileAsync.

Sedan anropar du två hjälpfunktioner: AddEnrollmentsToTextIndependentProfile, som du redan har definierat och SpeakerIdentify, som du ska definiera härnäst. Anropa slutligen DeleteProfileAsync för att rensa profilen.

Funktionen SpeakerIdentify

Definiera funktionen på SpeakerIdentify följande sätt:

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

I den här funktionen skapar du ett SpeakerIdentificationModel-objekt med metoden SpeakerIdentificationModel::FromProfiles . SpeakerIdentificationModel::FromProfiles accepterar en lista över VoiceProfile-objekt . I det här fallet skickar du in objektet VoiceProfile som du skapade tidigare. Om du vill kan du skicka in flera VoiceProfile objekt, var och en registrerad med ljudexempel från en annan röst.

Sedan uppmanar SpeechRecognizer::RecognizeOnceAsync dig att tala igen. Den här gången jämförs din röst med de registrerade röstprofilerna och returnerar den mest liknande röstprofilen.

Funktionen Main

Definiera slutligen funktionen enligt main följande:

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

Den här funktionen anropar de funktioner som du definierade tidigare. Först skapas ett VoiceProfileClient-objekt och ett SpeakerRecognizer-objekt .

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

Objektet VoiceProfileClient används för att skapa, registrera och ta bort röstprofiler. Objektet SpeakerRecognizer används för att verifiera talexempel mot en eller flera registrerade röstprofiler.

Ändra ljudinmatningstyp

Exemplen i den här artikeln använder enhetens standardmikrofon som indata för ljudexempel. I scenarier där du behöver använda ljudfiler i stället för mikrofoninmatning ändrar du följande rad:

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

till:

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

Eller ersätt all användning av audio_config med Audio::AudioConfig::FromWavFileInput. Du kan också ha blandade indata med hjälp av en mikrofon för registrering och filer för verifiering, till exempel.

Referensdokumentation | Paket (Go) | Ytterligare exempel på GitHub

I den här snabbstarten lär du dig grundläggande designmönster för talarigenkänning med hjälp av Speech SDK, inklusive:

  • Textberoende och textoberoende verifiering.
  • Talaridentifiering för att identifiera ett röstexempel bland en grupp röster.
  • Ta bort röstprofiler.

En övergripande titt på begrepp för talarigenkänning finns i artikeln Översikt . En lista över plattformar som stöds finns i referensnoden i det vänstra fönstret.

Viktigt

Microsoft begränsar åtkomsten till talarigenkänning. Använd för att använda det via formuläret för begränsad åtkomstgranskning för Azure AI-talarigenkänning . Efter godkännandet kan du komma åt API:erna för talarigenkänning.

Förutsättningar

Konfigurera miljön

Installera Speech SDK för Go. Mer krav finns i installationsguiden för SDK

Utföra oberoende identifiering

Följ de här stegen för att skapa en ny GO-modul.

  1. Öppna en kommandotolk där du vill ha den nya modulen och skapa en ny fil med namnet independent-identification.go.

  2. Ersätt innehållet i independent-identification.go med följande kod.

    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. I independent-identification.goersätter du YourSubscriptionKey med din Speech-resursnyckel och ersätter YourServiceRegion med din Speech-resursregion.

    Viktigt

    Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln för Azure AI-tjänster.

Kör följande kommandon för att skapa en go.mod fil som länkar till komponenter som finns på GitHub:

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

Skapa och kör nu koden:

go build
go run independent-identification

Utföra oberoende verifiering

Följ de här stegen för att skapa en ny GO-modul.

  1. Öppna en kommandotolk där du vill ha den nya modulen och skapa en ny fil med namnet independent-verification.go.

  2. Ersätt innehållet i independent-verification.go med följande kod.

    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. I independent-verification.goersätter du YourSubscriptionKey med din Speech-resursnyckel och ersätter YourServiceRegion med din Speech-resursregion.

Kör följande kommandon för att skapa en go.mod fil som länkar till komponenter som finns på GitHub:

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

Skapa och kör nu koden:

go build
go run independent-verification

Rensa resurser

Du kan använda Azure Portal eller Azure Command Line Interface (CLI) för att ta bort talresursen som du skapade.

Referensdokumentation | Ytterligare exempel på GitHub

Speech SDK för Java stöder talarigenkänning, men vi har ännu inte tagit med någon guide här. Välj ett annat programmeringsspråk för att komma igång och lära dig mer om begreppen, eller se Java-referensen och exemplen som är länkade från början av den här artikeln.

Referensdokumentation | Paket (npm) | Ytterligare exempel på GitHub | Källkod för bibliotek

I den här snabbstarten lär du dig grundläggande designmönster för talarigenkänning med hjälp av Speech SDK, inklusive:

  • Textberoende och textoberoende verifiering.
  • Talaridentifiering för att identifiera ett röstexempel bland en grupp röster.
  • Ta bort röstprofiler.

En övergripande titt på begrepp för talarigenkänning finns i artikeln Översikt . En lista över plattformar som stöds finns i referensnoden i det vänstra fönstret.

Viktigt

Microsoft begränsar åtkomsten till talarigenkänning. Använd för att använda det via formuläret för begränsad åtkomstgranskning för Azure AI-talarigenkänning . Efter godkännandet kan du komma åt API:erna för talarigenkänning.

Förutsättningar

Installera Speech SDK

Innan du börjar måste du installera Speech SDK för JavaScript.

Beroende på målmiljön använder du något av följande:

Ladda ned och extrahera Speech SDK för JavaScript -microsoft.cognitiveservices.speech.sdk.bundle.js fil. Placera den i en mapp som är tillgänglig för HTML-filen.

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

Tips

Om du riktar in dig på en webbläsare och använder taggen <script> behövs inte prefixet sdk . Prefixet sdk är ett alias som används för att namnge modulen require .

Importera beroenden

Om du vill köra exemplen i den här artikeln lägger du till följande instruktioner överst i filen .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;

Dessa instruktioner importerar de bibliotek som krävs och hämtar prenumerationsnyckeln och regionen för Speech-tjänsten från miljövariablerna. De anger också sökvägar till ljudfiler som du ska använda i följande uppgifter.

Viktigt

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln för Azure AI-tjänster.

Skapa en hjälpfunktion

Lägg till följande hjälpfunktion för att läsa ljudfiler i strömmar för användning av Speech-tjänsten:

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

I den här funktionen använder du metoderna AudioInputStream.createPushStream och AudioConfig.fromStreamInput för att skapa ett AudioConfig-objekt . Det här AudioConfig objektet representerar en ljudström. Du kommer att använda flera av dessa AudioConfig objekt under följande uppgifter.

Textberoende verifiering

Talarverifiering är att bekräfta att en talare matchar en känd eller registrerad röst. Det första steget är att registrera en röstprofil så att tjänsten har något att jämföra framtida röstexempel med. I det här exemplet registrerar du profilen med hjälp av en textberoende strategi, som kräver en specifik lösenfras som ska användas för registrering och verifiering. En lista över lösenfraser som stöds finns i referensdokumenten .

Funktionen TextDependentVerification

Börja med att TextDependentVerification skapa funktionen.

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

Den här funktionen skapar ett VoiceProfile-objekt med metoden VoiceProfileClient.createProfileAsync . Det finns tre typer av VoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

I det här fallet skickar VoiceProfileType.TextDependentVerification du till VoiceProfileClient.createProfileAsync.

Sedan anropar du två hjälpfunktioner som du definierar härnäst, AddEnrollmentsToTextDependentProfile och SpeakerVerify. Anropa slutligen VoiceProfileClient.deleteProfileAsync för att ta bort profilen.

Funktionen AddEnrollmentsToTextDependentProfile

Definiera följande funktion för att registrera en röstprofil:

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

I den här funktionen anropar du den GetAudioConfigFromFile funktion som du definierade tidigare för att skapa AudioConfig objekt från ljudexempel. Dessa ljudexempel innehåller en lösenfras, till exempel "Min röst är mitt pass, verifiera mig". Sedan registrerar du dessa ljudexempel med hjälp av metoden VoiceProfileClient.enrollProfileAsync .

Funktionen SpeakerVerify

Definiera SpeakerVerify på följande sätt:

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

I den här funktionen skapar du ett SpeakerVerificationModel-objekt med metoden SpeakerVerificationModel.FromProfile och skickar in VoiceProfile-objektet som du skapade tidigare.

Sedan anropar du metoden SpeechRecognizer.recognizeOnceAsync för att verifiera ett ljudexempel som innehåller samma lösenfras som de ljudexempel som du registrerade tidigare. SpeechRecognizer.recognizeOnceAsync returnerar ett SpeakerRecognitionResult-objekt , vars score egenskap innehåller en likhetspoäng som sträcker sig från 0,0 till 1,0. Objektet SpeakerRecognitionResult innehåller också en reason egenskap av typen ResultReason. Om verifieringen lyckades ska egenskapen reason ha värdet RecognizedSpeaker.

Textoberoende verifiering

Till skillnad från textberoende verifiering, textoberoende verifiering:

  • Kräver inte att en viss lösenfras talas. Vad som helst kan sägas.
  • Kräver inte tre ljudexempel men kräver 20 sekunders totalt ljud.

Funktionen TextIndependentVerification

Börja med att TextIndependentVerification skapa funktionen.

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

Precis som funktionen skapar den TextDependentVerification här funktionen ett VoiceProfile-objekt med metoden VoiceProfileClient.createProfileAsync .

I det här fallet skickar VoiceProfileType.TextIndependentVerification du till createProfileAsync.

Sedan anropar du två hjälpfunktioner: AddEnrollmentsToTextIndependentProfile, som du definierar härnäst och SpeakerVerify, som du redan har definierat. Anropa slutligen VoiceProfileClient.deleteProfileAsync för att ta bort profilen.

AddEnrollmentsToTextIndependentProfile

Definiera följande funktion för att registrera en röstprofil:

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

I den här funktionen anropar du den GetAudioConfigFromFile funktion som du definierade tidigare för att skapa AudioConfig objekt från ljudexempel. Sedan registrerar du dessa ljudexempel med hjälp av metoden VoiceProfileClient.enrollProfileAsync .

Talaridentifiering

Talaridentifiering används för att avgöra vem som talar från en viss grupp med registrerade röster. Processen liknar textoberoende verifiering. Den största skillnaden är möjligheten att verifiera mot flera röstprofiler samtidigt i stället för att verifiera mot en enda profil.

Funktionen TextIndependentIdentification

Börja med att TextIndependentIdentification skapa funktionen.

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

Precis som TextDependentVerification funktionerna och TextIndependentVerification skapar den här funktionen ett VoiceProfile-objekt med metoden VoiceProfileClient.createProfileAsync .

I det här fallet skickar VoiceProfileType.TextIndependentIdentification du till VoiceProfileClient.createProfileAsync.

Sedan anropar du två hjälpfunktioner: AddEnrollmentsToTextIndependentProfile, som du redan har definierat och SpeakerIdentify, som du ska definiera härnäst. Anropa slutligen VoiceProfileClient.deleteProfileAsync för att ta bort profilen.

Funktionen SpeakerIdentify

Definiera funktionen enligt SpeakerIdentify följande:

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

I den här funktionen skapar du ett SpeakerIdentificationModel-objekt med metoden SpeakerIdentificationModel.fromProfiles och skickar in voiceprofile-objektet som du skapade tidigare.

Därefter anropar du metoden SpeechRecognizer.recognizeOnceAsync och skickar in ett ljudexempel. SpeechRecognizer.recognizeOnceAsync försöker identifiera rösten för det här ljudexemplet baserat på de VoiceProfile objekt som du använde för att skapa SpeakerIdentificationModel. Den returnerar ett SpeakerRecognitionResult-objekt , vars profileId egenskap identifierar matchande VoiceProfile, om någon, medan score egenskapen innehåller en likhetspoäng som sträcker sig från 0,0 till 1,0.

Huvudfunktion

Definiera slutligen funktionen enligt main följande:

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

Den här funktionen skapar ett VoiceProfileClient-objekt som används för att skapa, registrera och ta bort röstprofiler. Sedan anropas de funktioner som du definierade tidigare.

Referensdokumentation | Paket (ladda ned) | Ytterligare exempel på GitHub

Speech SDK för Objective-C stöder inte talarigenkänning. Välj ett annat programmeringsspråk eller objective-C-referensen och exempel som är länkade från början av den här artikeln.

Referensdokumentation | Paket (ladda ned) | Ytterligare exempel på GitHub

Speech SDK för Swift stöder inte talarigenkänning. Välj ett annat programmeringsspråk eller Swift-referensen och exempel som är länkade från början av den här artikeln.

Referensdokumentation | Paket (PyPi) | Ytterligare exempel på GitHub

Speech SDK för Python stöder inte talarigenkänning. Välj ett annat programmeringsspråk eller Python-referensen och exempel som är länkade från början av den här artikeln.

Rest API-referens | för tal till textREST API för tal till text för kort ljudreferens | Ytterligare exempel på GitHub

I den här snabbstarten lär du dig grundläggande designmönster för talarigenkänning med hjälp av Speech SDK, inklusive:

  • Textberoende och textoberoende verifiering.
  • Talaridentifiering för att identifiera ett röstexempel bland en grupp röster.
  • Ta bort röstprofiler.

En övergripande titt på begrepp för talarigenkänning finns i artikeln Översikt . En lista över plattformar som stöds finns i referensnoden i det vänstra fönstret.

Viktigt

Microsoft begränsar åtkomsten till talarigenkänning. Använd för att använda det via formuläret för begränsad åtkomstgranskning för Azure AI-talarigenkänning . Efter godkännandet kan du komma åt API:erna för talarigenkänning.

Förutsättningar

Textberoende verifiering

Talarverifiering är att bekräfta att en talare matchar en känd eller registrerad röst. Det första steget är att registrera en röstprofil så att tjänsten har något att jämföra framtida röstexempel med. I det här exemplet registrerar du profilen med hjälp av en textberoende strategi, som kräver en specifik lösenfras som ska användas för registrering och verifiering. En lista över lösenfraser som stöds finns i referensdokumenten .

Börja med att skapa en röstprofil. Du måste infoga prenumerationsnyckeln och regionen för Speech-tjänsten i vart och ett av curl-kommandona i den här artikeln.

Viktigt

Kom ihåg att ta bort nyckeln från koden när du är klar och publicera den aldrig offentligt. För produktion använder du ett säkert sätt att lagra och komma åt dina autentiseringsuppgifter som Azure Key Vault. Mer information finns i säkerhetsartikeln för Azure AI-tjänster.

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

Det finns tre typer av röstprofil:

  • Textberoende verifiering
  • Textoberoende verifiering
  • Textoberoende identifiering

I det här fallet skapar du en textberoende verifieringsröstprofil. Du bör få följande svar:

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

Därefter registrerar du röstprofilen. --data-binary För parametervärdet anger du en ljudfil på datorn som innehåller en av de lösenfraser som stöds, till exempel "Min röst är mitt pass, verifiera mig". Du kan spela in en ljudfil med en app som Windows Röstinspelaren. Eller så kan du generera den med hjälp av text till tal.

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'

Du bör få följande svar:

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

Det här svaret anger att du måste registrera ytterligare två ljudexempel.

När du har registrerat totalt tre ljudexempel bör du få följande svar:

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

Nu är du redo att verifiera ett ljudexempel mot röstprofilen. Det här ljudexemplet bör innehålla samma lösenfras som de exempel som du använde för att registrera röstprofilen.

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'

Du bör få följande svar:

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

Accept innebär att lösenfrasen matchade och verifieringen lyckades. Svaret innehåller också en likhetspoäng som sträcker sig från 0,0 till 1,0.

Ta bort röstprofilen för att slutföra.

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'

Det finns inget svar.

Textoberoende verifiering

Till skillnad från textberoende verifiering, textoberoende verifiering:

  • Kräver inte att en viss lösenfras talas. Vad som helst kan sägas.
  • Kräver inte tre ljudexempel men kräver 20 sekunders totalt ljud.

Börja med att skapa en textoberoende verifieringsprofil.

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

Du bör få följande svar:

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

Registrera sedan röstprofilen. I stället för att skicka in tre ljudexempel måste du skicka in ljudexempel som innehåller totalt 20 sekunders ljud.

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'

När du har skickat tillräckligt med ljudexempel bör du få följande svar:

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

Nu är du redo att verifiera ett ljudexempel mot röstprofilen. Återigen behöver det här ljudexemplet inte innehålla någon lösenfras. Det kan innehålla valfritt tal, men det måste innehålla minst fyra sekunders ljud.

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'

Du bör få följande svar:

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

Accept innebär att verifieringen lyckades. Svaret innehåller också en likhetspoäng som sträcker sig från 0,0 till 1,0.

Ta bort röstprofilen för att slutföra.

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'

Det finns inget svar.

Talaridentifiering

Talaridentifiering används för att avgöra vem som talar från en viss grupp med registrerade röster. Processen liknar textoberoende verifiering. Den största skillnaden är möjligheten att verifiera mot flera röstprofiler samtidigt i stället för att verifiera mot en enda profil.

Börja med att skapa en textoberoende identifieringsprofil.

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

Du bör få följande svar:

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

Därefter registrerar du röstprofilen. Återigen måste du skicka ljudexempel som innehåller totalt 20 sekunders ljud. De här exemplen behöver inte innehålla någon lösenfras.

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'

När du har skickat tillräckligt med ljudexempel bör du få följande svar:

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

Nu är du redo att identifiera ett ljudexempel med hjälp av röstprofilen. Identifieringskommandot accepterar en kommaavgränsad lista över möjliga röstprofil-ID:t. I det här fallet skickar du ID:t för röstprofilen som du skapade tidigare. Om du vill kan du skicka in flera röstprofil-ID:t där varje röstprofil registreras med ljudexempel från en annan röst.

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

Du bör få följande svar:

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

Svaret innehåller ID:t för röstprofilen som bäst matchar det ljudexempel som du skickade. Den innehåller också en lista över kandidatröstprofiler, rangordnade i likhetsordning.

Ta bort röstprofilen för att slutföra.

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'

Det finns inget svar.

Speech CLI stöder talarigenkänning, men vi har ännu inte tagit med någon guide här. Välj ett annat programmeringsspråk för att komma igång och lära dig mer om begreppen.

Nästa steg