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
- Azure-prenumeration – Skapa en kostnadsfritt.
- Skapa en Speech-resurs i Azure Portal.
- Din Speech-resursnyckel och -region. När speech-resursen har distribuerats väljer du Gå till resurs för att visa och hantera nycklar. Mer information om Resurser för Azure AI-tjänster finns i Hämta nycklarna för din resurs.
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 VoiceProfile
och 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 profileNames
som 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
- Azure-prenumeration – Skapa en kostnadsfritt.
- Skapa en Speech-resurs i Azure Portal.
- Din Speech-resursnyckel och -region. När speech-resursen har distribuerats väljer du Gå till resurs för att visa och hantera nycklar. Mer information om Resurser för Azure AI-tjänster finns i Hämta nycklarna för din resurs.
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
- Azure-prenumeration – Skapa en kostnadsfritt.
- Skapa en Speech-resurs i Azure Portal.
- Din Speech-resursnyckel och -region. När speech-resursen har distribuerats väljer du Gå till resurs för att visa och hantera nycklar. Mer information om Azure AI-tjänstresurser finns i Hämta nycklarna för din resurs.
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.
Öppna en kommandotolk där du vill ha den nya modulen och skapa en ny fil med namnet
independent-identification.go
.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') }
I
independent-identification.go
ersätter duYourSubscriptionKey
med din Speech-resursnyckel och ersätterYourServiceRegion
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.
Öppna en kommandotolk där du vill ha den nya modulen och skapa en ny fil med namnet
independent-verification.go
.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') }
I
independent-verification.go
ersätter duYourSubscriptionKey
med din Speech-resursnyckel och ersätterYourServiceRegion
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
- Azure-prenumeration – Skapa en kostnadsfritt.
- Skapa en Speech-resurs i Azure Portal.
- Din Speech-resursnyckel och -region. När speech-resursen har distribuerats väljer du Gå till resurs för att visa och hantera nycklar. Mer information om Azure AI-tjänstresurser finns i Hämta nycklarna för din resurs.
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
- Azure-prenumeration – Skapa en kostnadsfritt.
- Skapa en Speech-resurs i Azure Portal.
- Din Speech-resursnyckel och -region. När speech-resursen har distribuerats väljer du Gå till resurs för att visa och hantera nycklar. Mer information om Azure AI-tjänstresurser finns i Hämta nycklarna för din resurs.
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.