Краткое руководство. Распознавание и проверка говорящего
Справочная документация | Пакет (NuGet) | Дополнительные примеры в GitHub
В этом руководстве показаны базовые конструктивные шаблоны для распознавания говорящего с помощью пакета SDK службы "Речь". В статье рассматриваются следующие темы:
- Проверка, зависящая от текста и не зависящая от текста.
- Идентификация говорящего для идентификации образца голоса в группе голосов.
- Удаление речевых профилей.
Общие сведения о концепциях распознавания говорящего см. в статье Обзор. Список поддерживаемых платформ см. на узле ссылки на панели навигации слева.
Важно!
Корпорация Майкрософт ограничивает доступ к распознаванию говорящего. Примените его с помощью формы azure AI Speaker Recognition Limited Access Review( Проверка ограниченного доступа). После утверждения можно получить доступ к API Распознавания говорящего.
Предварительные требования
- Подписка Azure — создайте бесплатную учетную запись.
- Создайте ресурс службы "Речь" на портале Azure.
- Ключ и регион ресурса службы "Речь". После развертывания ресурса службы "Речь" выберите Перейти к ресурсу для просмотра ключей и управления ими. Дополнительные сведения о ресурсах служб ИИ Azure см. в статье Получение ключей для ресурса.
Установка пакета SDK службы "Речь"
Перед началом работы необходимо установить пакет SDK службы "Речь". В зависимости от используемой платформы выполните следующие действия:
Импорт зависимостей
Чтобы выполнить примеры из этой статьи, добавьте в начале скрипта следующие инструкции using
:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
Создание конфигурации службы "Речь"
Чтобы вызвать службу "Речь" с помощью пакета SDK для службы "Речь", необходимо создать экземпляр SpeechConfig
. В этом примере создается экземпляр SpeechConfig
с использованием ключа и региона подписки. Для оставшейся части этой статьи также создается стандартный код, который необходимо будет изменить, чтобы внести различные настройки.
Важно!
Не забудьте удалить ключ из кода, когда закончите, и никогда не публикуйте его в открытом доступе. Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения см. в статье о безопасности служб ИИ Azure.
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);
}
}
Проверка, зависящая от текста
Проверка говорящего является подтверждением того, что говорящий соответствует известному или зарегистрированному голосу. В первую очередь необходимо зарегистрировать речевой профиль, чтобы службе было с чем сравнивать будущие примеры голоса. В этом примере вы регистрируете профиль, используя стратегию text-dependent, при применении которой нужно указывать парольную фразу как для регистрации, так и для проверки. Список поддерживаемых парольных фраз см. в справочной документации.
Начните с создания следующей функции в классе Program
, чтобы зарегистрировать речевой профиль:
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}");
}
}
}
}
В этой функции await client.CreateProfileAsync()
— то, что фактически создает новый речевой профиль. После ее создания вы указываете, как будут вводиться звуковые образцы. В данном примере для записи звука с устройства ввода по умолчанию используется AudioConfig.FromDefaultMicrophoneInput()
. Затем вы регистрируете звуковые образцы в цикле while
, отслеживающем количество оставшихся образцов, которые должны быть зарегистрированы. В каждой итерации client.EnrollProfileAsync(profile, audioInput)
предлагает произнести парольную фразу в микрофон и добавляет этот образец в речевой профиль.
После завершения регистрации вызывается await SpeakerVerify(config, profile, profileMapping)
для проверки только что созданного профиля. Добавьте еще одну функцию для определения 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}");
}
В этой функции вы передаете только что созданный объект VoiceProfile
, чтобы инициализировать модель для проверки. Затем await speakerRecognizer.RecognizeOnceAsync(model)
предлагает еще раз произнести парольную фразу. На этот раз она будет проверяться на соответствие речевому профилю, после чего будет возвращаться показатель подобия от 0,0 до 1,0. Объект result
также возвращает Accept
или Reject
в зависимости от того, соответствует ли парольная фраза.
Затем измените функцию Main()
для вызова новых созданных функций. Кроме того, обратите внимание, что вы создаете Dictionary<string, string>
для передачи по ссылке через вызовы функции. Это связано с тем, что для обеспечения конфиденциальности служба не позволяет хранить удобное для восприятия человеком имя с созданным VoiceProfile
и сохраняет только идентификационный номер. В функции VerificationEnroll
вы добавляете в этот словарь запись с только что созданным идентификатором и текстовым именем. В сценариях разработки приложений, где необходимо отображать удобное для восприятия имя, необходимо хранить это сопоставление где-нибудь еще, так как служба не может его хранить.
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();
}
Выполните скрипт. Вам будет предложено произнести фразу "Мой голос — мой паспорт, проверьте меня" три раза для регистрации и еще один раз для проверки. Возвращаемый результат является показателем подобия, который можно использовать для создания собственных настраиваемых порогов для проверки.
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
Проверка, не зависящая от текста
В отличие от проверки, зависящей от текста, для проверки, не зависящей от текста, не требуются три примера звуковых данных, но требуется, чтобы общая длительность звуковых данных составляла 20 секунд.
Внесите несколько простых изменений в функцию VerificationEnroll
, чтобы переключиться на проверку, не зависящую от текста. Сначала измените тип проверки на VoiceProfileType.TextIndependentVerification
. Затем измените цикл while
, чтобы он отслеживал result.RemainingEnrollmentsSpeechLength
и запрос на произнесение речи выводился до тех пор, пока не будут записаны 20 секунд.
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}");
}
}
}
}
Снова запустите программу. Возвращается показатель подобия.
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
Идентификация говорящего
Идентификация говорящего используется для определения, кто именно говорит из определенной группы зарегистрированных голосов. Этот процесс похож на проверку, не зависящую от текста. Основное отличие заключается в том, что можно сравнивать не с одним, а сразу с несколькими речевыми профилями.
Создайте функцию IdentificationEnroll
для регистрации нескольких речевых профилей. Процесс регистрации каждого профиля аналогичен процессу регистрации при проверке, не зависящей от текста, и для каждого профиля требуется 20 секунд речи. Эта функция принимает список строк profileNames
и создает новый речевой профиль для каждого имени в списке. Функция возвращает список объектов VoiceProfile
, которые используются в следующей функции для определения говорящего.
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;
}
Создайте следующую функцию SpeakerIdentification
, чтобы отправить запрос на идентификацию. Основное отличие этой функции от запроса проверки говорящего заключается в использовании метода SpeakerIdentificationModel.FromProfiles()
, который принимает список объектов VoiceProfile
.
public static async Task SpeakerIdentification(SpeechConfig config, List<VoiceProfile> voiceProfiles, Dictionary<string, string> profileMapping)
{
var speakerRecognizer = new SpeakerRecognizer(config, AudioConfig.FromDefaultMicrophoneInput());
var model = SpeakerIdentificationModel.FromProfiles(voiceProfiles);
Console.WriteLine("Speak some text to identify who it is from your list of enrolled speakers.");
var result = await speakerRecognizer.RecognizeOnceAsync(model);
Console.WriteLine($"The most similar voice profile is {profileMapping[result.ProfileId]} with similarity score {result.Score}");
}
Измените функцию Main()
следующим образом. Вы создаете список строк profileNames
, который передаете в функцию IdentificationEnroll()
. Появится запрос на создание нового речевого профиля для каждого имени в этом списке, поэтому можно добавить дополнительные имена для создания дополнительных профилей для друзей или коллег.
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();
}
Выполните скрипт. Появится предложение произнести что-нибудь для регистрации образцов голоса для первого профиля. После завершения регистрации вам будет предложено повторить эту процедуру для каждого имени в списке profileNames
. После завершения всех регистраций будет предложено, чтобы кто-нибудь что-нибудь сказал, и служба попытается опознать этого пользователя на основе зарегистрированных речевых профилей.
В этом примере возвращается только ближайшее соответствие и показатель подобия, но можно получить полный ответ, включающий пять главных показателей подобия, добавив string json = result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult)
в вашу функцию SpeakerIdentification
.
Изменение типа входных звуковых данных
В примерах, приведенных в этой статье, для записи образцов звука используется микрофон устройства по умолчанию. Если же необходимо использовать звуковые файлы вместо ввода с микрофона, измените любой экземпляр AudioConfig.FromDefaultMicrophoneInput()
на AudioConfig.FromWavFileInput(path/to/your/file.wav)
, чтобы переключиться на ввод файлов. Можно также использовать смешанные входные данные, например микрофон для регистрации и файлы для проверки.
Удаление регистраций речевых профилей
Чтобы удалить зарегистрированный профиль, используйте функцию DeleteProfileAsync()
в объекте VoiceProfileClient
. В следующем примере функции показано, как удалить речевой профиль для известного идентификатора речевого профиля:
public static async Task DeleteProfile(SpeechConfig config, string profileId)
{
using (var client = new VoiceProfileClient(config))
{
var profile = new VoiceProfile(profileId);
await client.DeleteProfileAsync(profile);
}
}
Справочная документация | Пакет (NuGet) | Дополнительные примеры в GitHub
В этом руководстве показаны базовые конструктивные шаблоны для распознавания говорящего с помощью пакета SDK службы "Речь". В статье рассматриваются следующие темы:
- Проверка, зависящая от текста и не зависящая от текста.
- Идентификация говорящего для идентификации образца голоса в группе голосов.
- Удаление речевых профилей.
Общие сведения о концепциях распознавания говорящего см. в статье Обзор. Список поддерживаемых платформ см. на узле ссылки на панели навигации слева.
Важно!
Корпорация Майкрософт ограничивает доступ к распознаванию говорящего. Примените его с помощью формы azure AI Speaker Recognition Limited Access Review( Проверка ограниченного доступа). После утверждения можно получить доступ к API Распознавания говорящего.
Предварительные требования
- Подписка Azure — создайте бесплатную учетную запись.
- Создайте ресурс службы "Речь" на портале Azure.
- Ключ и регион ресурса службы "Речь". После развертывания ресурса службы "Речь" выберите Перейти к ресурсу для просмотра ключей и управления ими. Дополнительные сведения о ресурсах служб ИИ Azure см. в статье Получение ключей для ресурса.
Установка пакета SDK службы "Речь"
Перед началом работы необходимо установить пакет SDK службы "Речь". В зависимости от используемой платформы выполните следующие действия:
Импорт зависимостей
Чтобы выполнить примеры из этой статьи, добавьте в начале CPP-файла следующие инструкции:
#include <iostream>
#include <stdexcept>
// Note: Install the NuGet package Microsoft.CognitiveServices.Speech.
#include <speechapi_cxx.h>
using namespace std;
using namespace Microsoft::CognitiveServices::Speech;
// Note: Change the locale if desired.
auto profile_locale = "en-us";
auto audio_config = Audio::AudioConfig::FromDefaultMicrophoneInput();
auto ticks_per_second = 10000000;
Создание конфигурации службы "Речь"
Чтобы вызвать службу "Речь" с помощью пакета SDK для службы "Речь", создайте класс SpeechConfig
. Этот класс содержит сведения о вашей подписке, такие как ключ и связанный регион, конечная точка, узел или маркер авторизации.
Важно!
Не забудьте удалить ключ из кода, когда закончите, и никогда не публикуйте его в открытом доступе. Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения см. в статье о безопасности служб ИИ Azure.
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;
}
Проверка, зависящая от текста
Проверка говорящего является подтверждением того, что говорящий соответствует известному или зарегистрированному голосу. В первую очередь необходимо зарегистрировать речевой профиль, чтобы службе было с чем сравнивать будущие примеры голоса. В этом примере вы регистрируете профиль, используя стратегию text-dependent, при применении которой нужно указывать парольную фразу как для регистрации, так и для проверки. Список поддерживаемых парольных фраз см. в справочной документации.
Функция TextDependentVerification
Начните с создания функции TextDependentVerification
:
void TextDependentVerification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
std::cout << "Text Dependent Verification:\n\n";
// Create the profile.
auto profile = client->CreateProfileAsync(VoiceProfileType::TextDependentVerification, profile_locale).get();
std::cout << "Created profile ID: " << profile->GetId() << "\n";
AddEnrollmentsToTextDependentProfile(client, profile);
SpeakerVerify(profile, recognizer);
// Delete the profile.
client->DeleteProfileAsync(profile);
}
Эта функция создает объект VoiceProfile с помощью метода CreateProfileAsync. Здесь возможны три вариантаVoiceProfile
:
- TextIndependentIdentification
- TextDependentVerification
- TextIndependentVerification
В этом примере VoiceProfileType::TextDependentVerification
передается в CreateProfileAsync
.
Затем нужно вызвать две вспомогательные функции AddEnrollmentsToTextDependentProfile
и SpeakerVerify
, которые вы определяете далее. Наконец, вызовите DeleteProfileAsync, чтобы очистить профиль.
Функция AddEnrollmentsToTextDependentProfile
Определите следующую функцию, чтобы зарегистрировать речевой профиль:
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";
}
В этой функции вы регистрируете звуковые образцы в цикле while
, отслеживающем количество оставшихся образцов, которые должны быть зарегистрированы. В каждой итерации EnrollProfileAsync предлагает произнести парольную фразу в микрофон и добавляет этот образец в речевой профиль.
Функция SpeakerVerify
Определите SpeakerVerify
следующим образом:
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";
}
В этой функции вы создаете объект SpeakerVerificationModel с помощью метода SpeakerVerificationModel::FromProfile, передавая ранее созданный объект VoiceProfile.
Затем SpeechRecognizer::RecognizeOnceAsync предлагает снова произнести парольную фразу. На этот раз она будет проверяться на соответствие речевому профилю, после чего будет возвращаться показатель подобия от 0,0 до 1,0. Объект SpeakerRecognitionResult также возвращает Accept
или Reject
в зависимости от того, соответствует ли парольная фраза.
Проверка, не зависящая от текста
В отличие от проверки, зависящей от текста, для проверки, не зависящей от текста, не требуются три примера звуковых данных, но требуется, чтобы общая длительность звуковых данных составляла 20 секунд.
Функция TextIndependentVerification
Начните с создания функции TextIndependentVerification
:
void TextIndependentVerification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
std::cout << "Text Independent Verification:\n\n";
// Create the profile.
auto profile = client->CreateProfileAsync(VoiceProfileType::TextIndependentVerification, profile_locale).get();
std::cout << "Created profile ID: " << profile->GetId() << "\n";
AddEnrollmentsToTextIndependentProfile(client, profile);
SpeakerVerify(profile, recognizer);
// Delete the profile.
client->DeleteProfileAsync(profile);
}
Как и функция TextDependentVerification
, эта функция создает объект VoiceProfile с помощью метода CreateProfileAsync.
В этом примере VoiceProfileType::TextIndependentVerification
передается в CreateProfileAsync
.
Затем нужно вызвать две вспомогательные функции: AddEnrollmentsToTextIndependentProfile
(определяется далее) и SpeakerVerify
(уже определена). Наконец, вызовите DeleteProfileAsync, чтобы очистить профиль.
AddEnrollmentsToTextIndependentProfile
Определите следующую функцию, чтобы зарегистрировать речевой профиль:
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";
}
В этой функции вы регистрируете звуковые образцы в цикле while
, отслеживающем количество секунд оставшегося звука, которое должно быть зарегистрировано. В каждой итерации EnrollProfileAsync предлагает говорить в микрофон и добавляет этот образец в речевой профиль.
Идентификация говорящего
Идентификация говорящего используется для определения, кто именно говорит из определенной группы зарегистрированных голосов. Этот процесс похож на проверку, не зависящую от текста. Основное отличие заключается в том, что можно сравнивать не с одним, а сразу с несколькими речевыми профилями.
Функция TextIndependentIdentification
Начните с создания функции TextIndependentIdentification
:
void TextIndependentIdentification(shared_ptr<VoiceProfileClient> client, shared_ptr<SpeakerRecognizer> recognizer)
{
std::cout << "Speaker Identification:\n\n";
// Create the profile.
auto profile = client->CreateProfileAsync(VoiceProfileType::TextIndependentIdentification, profile_locale).get();
std::cout << "Created profile ID: " << profile->GetId() << "\n";
AddEnrollmentsToTextIndependentProfile(client, profile);
SpeakerIdentify(profile, recognizer);
// Delete the profile.
client->DeleteProfileAsync(profile);
}
Как и функции TextDependentVerification
и TextIndependentVerification
, эта функция создает объект VoiceProfile с помощью метода CreateProfileAsync.
В этом примере VoiceProfileType::TextIndependentIdentification
передается в CreateProfileAsync
.
Затем нужно вызвать две вспомогательные функции: уже определенную вами AddEnrollmentsToTextIndependentProfile
и SpeakerIdentify
, которую вы определите. Наконец, вызовите DeleteProfileAsync, чтобы очистить профиль.
Функция SpeakerIdentify
Определите функцию SpeakerIdentify
следующим образом:
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";
}
В этой функции вы создаете объект SpeakerIdentificationModel с помощью метода SpeakerIdentificationModel::FromProfiles. Метод SpeakerIdentificationModel::FromProfiles
принимает список объектов VoiceProfile. В этом случае вы передадите ранее созданный объект VoiceProfile
. При необходимости можно передать несколько объектов VoiceProfile
, каждый из которых зарегистрирован с помощью звуковых примеров другого голоса.
Затем SpeechRecognizer::RecognizeOnceAsync предлагает говорить снова. На этот раз он сравнивает ваш голос с зарегистрированными речевыми профилями и возвращает самый похожий речевой профиль.
Функция main
Наконец, определите функцию main
следующим образом:
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";
}
Эта функция вызывает ранее определенные функции. Сначала она создает объекты VoiceProfileClient и SpeakerRecognizer.
auto speech_config = GetSpeechConfig();
auto client = VoiceProfileClient::FromConfig(speech_config);
auto recognizer = SpeakerRecognizer::FromConfig(speech_config, audio_config);
Объект VoiceProfileClient
используется для создания, регистрации и удаления речевых профилей. Объект SpeakerRecognizer
используется для проверки примеров речи по одному или нескольким зарегистрированным речевым профилям.
Изменение типа входных звуковых данных
В примерах, приведенных в этой статье, для записи образцов звука используется микрофон устройства по умолчанию. Если вместо ввода с микрофона необходимо использовать звуковые файлы, просто следующую строку:
auto audio_config = Audio::AudioConfig::FromDefaultMicrophoneInput();
на:
auto audio_config = Audio::AudioConfig::FromWavFileInput("path/to/your/file.wav");
Или замените audio_config
на Audio::AudioConfig::FromWavFileInput. Можно также использовать смешанные входные данные, например микрофон для регистрации и файлы для проверки.
Справочная документация | Пакет (Go) | Дополнительные примеры в GitHub
В этом руководстве показаны базовые конструктивные шаблоны для распознавания говорящего с помощью пакета SDK службы "Речь". В статье рассматриваются следующие темы:
- Проверка, зависящая от текста и не зависящая от текста.
- Идентификация говорящего для идентификации образца голоса в группе голосов.
- Удаление речевых профилей.
Общие сведения о концепциях распознавания говорящего см. в статье Обзор. Список поддерживаемых платформ см. на узле ссылки на панели навигации слева.
Важно!
Корпорация Майкрософт ограничивает доступ к распознаванию говорящего. Примените его для использования с помощью формы Azure AI Speaker Recognition Limited Access Review . После утверждения можно получить доступ к API Распознавания говорящего.
Предварительные требования
- Подписка Azure — создайте бесплатную учетную запись.
- Создайте ресурс службы "Речь" на портале Azure.
- Ключ и регион ресурса службы "Речь". После развертывания ресурса службы "Речь" выберите Перейти к ресурсу для просмотра ключей и управления ими. Дополнительные сведения о ресурсах служб ИИ Azure см. в статье Получение ключей для ресурса.
Настройка среды
Установите пакет SDK службы "Речь" для Go. Сначала ознакомьтесь со статьей Руководство по установке пакета SDK, чтобы узнать о дополнительных требованиях.
Выполнение независимой идентификации
Выполните следующие действия, чтобы создать новый модуль GO.
Откройте командную строку, в которой должен быть создан новый модуль, и создайте новый файл с именем
independent-identification.go
.Замените все содержимое
independent-identification.go
следующим кодом: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') }
В
independent-identification.go
заменитеYourSubscriptionKey
на ключ ресурса службы "Речь" и заменитеYourServiceRegion
на регион ресурса службы "Речь".Важно!
Не забудьте удалить ключ из кода, когда закончите, и никогда не публикуйте его в открытом доступе. Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения см. в статье о безопасности служб ИИ Azure.
Выполните приведенные ниже команды, чтобы создать файл go.mod
со ссылкой на компоненты, размещенные в GitHub:
go mod init independent-identification
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Теперь можно приступить к сборке и выполнению кода:
go build
go run independent-identification
Выполнение независимой проверки
Выполните следующие действия, чтобы создать новый модуль GO.
Откройте командную строку, в которой должен быть создан новый модуль, и создайте новый файл с именем
independent-verification.go
.Замените все содержимое
independent-verification.go
следующим кодом: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') }
В
independent-verification.go
заменитеYourSubscriptionKey
на ключ ресурса службы "Речь" и заменитеYourServiceRegion
на регион ресурса службы "Речь".
Выполните приведенные ниже команды, чтобы создать файл go.mod
со ссылкой на компоненты, размещенные в GitHub:
go mod init independent-verification
go get github.com/Microsoft/cognitive-services-speech-sdk-go
Теперь можно приступить к сборке и выполнению кода:
go build
go run independent-verification
Очистка ресурсов
Для удаления созданного ресурса службы "Речь" можно использовать портал Azure или интерфейс командной строки (CLI) Azure.
Справочная документация | Дополнительные примеры в GitHub
Пакет SDK службы "Речь" для Java поддерживает распознавание говорящего, но мы еще не включили в эту статью руководство по использованию этого пакета SDK. Выберите другой язык программирования, чтобы приступить к работе и ознакомиться с основными понятиями, или обратитесь к справочнику и примерам для языка Java, ссылки на которые приведены в начале этой статьи.
Справочная документация | Пакет (npm) | Дополнительные примеры в GitHub | Исходный код библиотеки
В этом руководстве показаны базовые конструктивные шаблоны для распознавания говорящего с помощью пакета SDK службы "Речь". В статье рассматриваются следующие темы:
- Проверка, зависящая от текста и не зависящая от текста.
- Идентификация говорящего для идентификации образца голоса в группе голосов.
- Удаление речевых профилей.
Общие сведения о концепциях распознавания говорящего см. в статье Обзор. Список поддерживаемых платформ см. на узле ссылки на панели навигации слева.
Важно!
Корпорация Майкрософт ограничивает доступ к распознаванию говорящего. Примените его для использования с помощью формы Azure AI Speaker Recognition Limited Access Review . После утверждения можно получить доступ к API Распознавания говорящего.
Предварительные требования
- Подписка Azure — создайте бесплатную учетную запись.
- Создайте ресурс службы "Речь" на портале Azure.
- Ключ и регион ресурса службы "Речь". После развертывания ресурса службы "Речь" выберите Перейти к ресурсу для просмотра ключей и управления ими. Дополнительные сведения о ресурсах служб ИИ Azure см. в статье Получение ключей для ресурса.
Установка пакета SDK службы "Речь"
Перед началом работы необходимо установить пакет SDK службы "Речь" для JavaScript.
В зависимости от целевой среды используйте один из следующих параметров:
Скачайте пакет SDK службы "Речь" для JavaScript, извлеките из него файл microsoft.cognitiveservices.speech.sdk.bundle.js. Поместите этот файл в папку, доступную для HTML-файла.
<script src="microsoft.cognitiveservices.speech.sdk.bundle.js"></script>;
Совет
Если в качестве платформы вы используете веб-браузер и применяете тег <script>
, использовать префикс sdk
не нужно. Префикс sdk
является псевдонимом для присвоения имени модулю require
.
Импорт зависимостей
Чтобы выполнить примеры из этой статьи, добавьте в начале 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;
Эти операторы импортируют необходимые библиотеки и получают ключ к подписке службы "Речь" и сведения о регионе из ваших переменных среды. Они также указывают путь к аудиофайлам, которые будут использоваться в следующих задачах.
Важно!
Не забудьте удалить ключ из кода, когда закончите, и никогда не публикуйте его в открытом доступе. Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения см. в статье о безопасности служб ИИ Azure.
Создание вспомогательной функции
Добавьте следующую вспомогательную функцию для чтения аудиофайлов в потоках, используемых службой "Речь":
function GetAudioConfigFromFile (file)
{
return sdk.AudioConfig.fromWavFileInput(fs.readFileSync(file));
}
В этой функции для создания объекта AudioConfig используются методы AudioInputStream.createPushStream и AudioConfig.fromStreamInput. Этот объект AudioConfig
представляет звуковой поток. Некоторые из этих объектов AudioConfig
понадобятся в следующих задачах.
Проверка, зависящая от текста
Проверка говорящего является подтверждением того, что говорящий соответствует известному или зарегистрированному голосу. В первую очередь необходимо зарегистрировать речевой профиль, чтобы службе было с чем сравнивать будущие примеры голоса. В этом примере вы регистрируете профиль, используя стратегию text-dependent, при применении которой нужно указывать парольную фразу как для регистрации, так и для проверки. Список поддерживаемых парольных фраз см. в справочной документации.
Функция TextDependentVerification
Начните с создания функции TextDependentVerification
.
async function TextDependentVerification(client, speech_config)
{
console.log ("Text Dependent Verification:\n");
var profile = null;
try {
const type = sdk.VoiceProfileType.TextDependentVerification;
// Create the profile.
profile = await client.createProfileAsync(type, profile_locale);
console.log ("Created profile ID: " + profile.profileId);
// Get the activation phrases
await GetActivationPhrases(type, profile_locale);
await AddEnrollmentsToTextDependentProfile(client, profile, passphrase_files);
const audio_config = GetAudioConfigFromFile(verify_file);
const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
await SpeakerVerify(profile, recognizer);
}
catch (error) {
console.log ("Error:\n" + error);
}
finally {
if (profile !== null) {
console.log ("Deleting profile ID: " + profile.profileId);
const deleteResult = await client.deleteProfileAsync (profile);
}
}
}
Эта функция создает объект VoiceProfile с помощью метода VoiceProfileClient.createProfileAsync. Здесь возможны три вариантаVoiceProfile
:
- TextIndependentIdentification
- TextDependentVerification
- TextIndependentVerification
В этом примере VoiceProfileType.TextDependentVerification
передается в VoiceProfileClient.createProfileAsync
.
Затем нужно вызвать две вспомогательные функции AddEnrollmentsToTextDependentProfile
и SpeakerVerify
, которые вы определяете далее. Наконец, для удаления профиля вызовите VoiceProfileClient.deleteProfileAsync.
Функция AddEnrollmentsToTextDependentProfile
Определите следующую функцию, чтобы зарегистрировать речевой профиль:
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);
}
}
В этой функции вы вызываете функцию GetAudioConfigFromFile
, определенную ранее, для создания объектов AudioConfig
из примеров звуковых данных. Эти примеры звуковых данных содержат парольную фразу, например "Мой голос — мой паспорт, проверь меня". Затем вы зарегистрируете эти примеры звуковых данных, используя метод VoiceProfileClient.enrollProfileAsync.
Функция SpeakerVerify
Определите SpeakerVerify
следующим образом:
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);
}
}
В этой функции вы создаете объект SpeakerVerificationModel с помощью метода SpeakerVerificationModel.FromProfile, передавая ранее созданный объект VoiceProfile.
Далее вызовите метод SpeechRecognizer.recognizeOnceAsync, чтобы проверить пример звуковых данных, который содержит ту же парольную фразу, что и в ранее зарегистрированном примере звуковых данных. SpeechRecognizer.recognizeOnceAsync
возвращает объект SpeakerRecognitionResult, свойство score
которого содержит оценку схожести в диапазоне 0,0–1,0. Объект SpeakerRecognitionResult
также содержит свойство reason
типа ResultReason. Если проверка прошла успешно, тогда свойство reason
должно иметь значение RecognizedSpeaker
.
Проверка, не зависящая от текста
Проверка, не зависящая от текста, отличается от проверки, зависящей от текста, в следующих аспектах.
- Определенная парольная фраза не требуется, можно произносить что угодно.
- Не требуются три примера звуковых данных, но требуется, чтобы длительность звуковых данных составляла 20 секунд.
Функция TextIndependentVerification
Начните с создания функции TextIndependentVerification
.
async function TextIndependentVerification(client, speech_config)
{
console.log ("Text Independent Verification:\n");
var profile = null;
try {
const type = sdk.VoiceProfileType.TextIndependentVerification;
// Create the profile.
profile = await client.createProfileAsync(type, profile_locale);
console.log ("Created profile ID: " + profile.profileId);
// Get the activation phrases
await GetActivationPhrases(type, profile_locale);
await AddEnrollmentsToTextIndependentProfile(client, profile, [identify_file]);
const audio_config = GetAudioConfigFromFile(passphrase_files[0]);
const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
await SpeakerVerify(profile, recognizer);
}
catch (error) {
console.log ("Error:\n" + error);
}
finally {
if (profile !== null) {
console.log ("Deleting profile ID: " + profile.profileId);
const deleteResult = await client.deleteProfileAsync (profile);
}
}
}
Как и функция TextDependentVerification
, эта функция создает объект VoiceProfile с помощью метода VoiceProfileClient.createProfileAsync.
В этом примере VoiceProfileType.TextIndependentVerification
передается в createProfileAsync
.
Затем нужно вызвать две вспомогательные функции: AddEnrollmentsToTextIndependentProfile
(определяется далее) и SpeakerVerify
(уже определена). Наконец, для удаления профиля вызовите VoiceProfileClient.deleteProfileAsync.
AddEnrollmentsToTextIndependentProfile
Определите следующую функцию, чтобы зарегистрировать речевой профиль:
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);
}
}
В этой функции вы вызываете функцию GetAudioConfigFromFile
, определенную ранее, для создания объектов AudioConfig
из примеров звуковых данных. Затем вы зарегистрируете эти примеры звуковых данных, используя метод VoiceProfileClient.enrollProfileAsync.
Идентификация говорящего
Идентификация говорящего используется для определения, кто именно говорит из определенной группы зарегистрированных голосов. Этот процесс похож на проверку, не зависящую от текста. Основное отличие заключается в том, что можно сравнивать не с одним, а сразу с несколькими речевыми профилями.
Функция TextIndependentIdentification
Начните с создания функции TextIndependentIdentification
.
async function TextIndependentIdentification(client, speech_config)
{
console.log ("Text Independent Identification:\n");
var profile = null;
try {
const type = sdk.VoiceProfileType.TextIndependentIdentification;
// Create the profile.
profile = await client.createProfileAsync(type, profile_locale);
console.log ("Created profile ID: " + profile.profileId);
// Get the activation phrases
await GetActivationPhrases(type, profile_locale);
await AddEnrollmentsToTextIndependentProfile(client, profile, [identify_file]);
const audio_config = GetAudioConfigFromFile(passphrase_files[0]);
const recognizer = new sdk.SpeakerRecognizer(speech_config, audio_config);
await SpeakerIdentify(profile, recognizer);
}
catch (error) {
console.log ("Error:\n" + error);
}
finally {
if (profile !== null) {
console.log ("Deleting profile ID: " + profile.profileId);
const deleteResult = await client.deleteProfileAsync (profile);
}
}
}
Как и функции TextDependentVerification
и TextIndependentVerification
, эта функция создает объект VoiceProfile с помощью метода VoiceProfileClient.createProfileAsync.
В этом примере VoiceProfileType.TextIndependentIdentification
передается в VoiceProfileClient.createProfileAsync
.
Затем нужно вызвать две вспомогательные функции: уже определенную вами AddEnrollmentsToTextIndependentProfile
и SpeakerIdentify
, которую вы определите. Наконец, для удаления профиля вызовите VoiceProfileClient.deleteProfileAsync.
Функция SpeakerIdentify
Определите функцию SpeakerIdentify
следующим образом:
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);
}
}
В этой функции вы создаете объект SpeakerIdentificationModel с помощью метода SpeakerIdentificationModel.fromProfiles, передавая ранее созданный объект VoiceProfile.
Затем вызовите метод SpeechRecognizer.recognizeOnceAsync и передайте пример звуковых данных.
Метод SpeechRecognizer.recognizeOnceAsync
пытается определить речь для этого примера звуковых данных на основе объектов VoiceProfile
, использованных для создания SpeakerIdentificationModel
. Он возвращает объект SpeakerRecognitionResult, свойство profileId
которого определяет совпадение с VoiceProfile
, если таковое имеется, а свойство score
содержит показатель подобия в диапазоне 0,0–1,0.
Функция main
Наконец, определите функцию main
следующим образом:
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();
Эта функция создает объект VoiceProfileClient, который используется при создании, регистрации и удалении голосовых профилей. Затем она вызывает функции, определенные ранее.
Справочная документация | Пакет (скачивание) | Дополнительные примеры в GitHub
Пакет SDK службы "Речь" для Objective-C не поддерживает распознавание говорящего. Выберите другой язык программирования или обратитесь к справочнику и примерам для языка Objective-C, ссылки на которые приведены в начале этой статьи.
Справочная документация | Пакет (скачивание) | Дополнительные примеры в GitHub
Пакет SDK службы "Речь" для Swift не поддерживает распознавание говорящего. Выберите другой язык программирования или обратитесь к справочнику и примерам для языка Swift, ссылки на которые приведены в начале этой статьи.
Справочная документация | Пакет (PyPi) | Дополнительные примеры в GitHub
Пакет SDK службы "Речь" для Python не поддерживает распознавание говорящего. Выберите другой язык программирования или обратитесь к справочнику и примерам для языка Python, ссылки на которые приведены в начале этой статьи.
Справочник | по REST API преобразования речи в текстRest API преобразования речи в текст для краткого справочника по звуку | Дополнительные примеры на GitHub
В этом руководстве показаны базовые конструктивные шаблоны для распознавания говорящего с помощью пакета SDK службы "Речь". В статье рассматриваются следующие темы:
- Проверка, зависящая от текста и не зависящая от текста.
- Идентификация говорящего для идентификации образца голоса в группе голосов.
- Удаление речевых профилей.
Общие сведения о концепциях распознавания говорящего см. в статье Обзор. Список поддерживаемых платформ см. на узле ссылки на панели навигации слева.
Важно!
Корпорация Майкрософт ограничивает доступ к распознаванию говорящего. Примените его для использования с помощью формы Azure AI Speaker Recognition Limited Access Review . После утверждения можно получить доступ к API Распознавания говорящего.
Предварительные требования
- Подписка Azure — создайте бесплатную учетную запись.
- Создайте ресурс службы "Речь" на портале Azure.
- Ключ и регион ресурса службы "Речь". После развертывания ресурса службы "Речь" выберите Перейти к ресурсу для просмотра ключей и управления ими. Дополнительные сведения о ресурсах служб ИИ Azure см. в статье Получение ключей для ресурса.
Проверка, зависящая от текста
Проверка говорящего является подтверждением того, что говорящий соответствует известному или зарегистрированному голосу. В первую очередь необходимо зарегистрировать речевой профиль, чтобы службе было с чем сравнивать будущие примеры голоса. В этом примере вы регистрируете профиль, используя стратегию text-dependent, при применении которой нужно указывать парольную фразу как для регистрации, так и для проверки. Список поддерживаемых парольных фраз см. в справочной документации.
Для начала создайте голосовой профиль. Необходимо вставить ключ и регион подписки службы "Речь" в каждую из этих команд в этой статье.
Важно!
Не забудьте удалить ключ из кода, когда закончите, и никогда не публикуйте его в открытом доступе. Для рабочей среды используйте безопасный способ хранения и доступа к учетным данным, например Azure Key Vault. Дополнительные сведения см. в статье о безопасности служб ИИ Azure.
# 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'\''
}'
Существует три типа речевого профиля:
- Текстозависимая проверка
- Текстонезависимая проверка
- Текстонезависимое распознавание
В этом случае вы создадите речевой профиль с зависимой от текста проверкой. Вы получите следующий ответ:
{
"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
}
Затем вам нужно зарегистрировать речевой профиль. В качестве значения параметра --data-binary
укажите звуковой файл на компьютере, который содержит одну из поддерживаемых парольных фраз, например "Мой голос — мой паспорт, проверь меня". Вы можете записать такой звуковой файл с помощью приложения, например Запись голоса Windows, Или вы можете создать его, используя текст для речи.
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'
Вы получите следующий ответ:
{
"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
}
Этот ответ указывает на то, что вам нужно зарегистрировать еще два примера звуковых данных.
После регистрации всех трех примеров звуковых данных вы получите следующий ответ:
{
"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
}
Теперь вы готовы сверить пример звуковых данных с речевым профилем. Этот пример звуковых данных должен содержать ту же парольную фразу, что и примеры, использованные для регистрации речевого профиля.
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'
Вы получите следующий ответ:
{
"recognitionResult": "Accept",
"score": 1.0
}
Accept
означает, что парольная фраза сопоставлена и проверка прошла успешно. Ответ также содержит показатель подобия в диапазоне от 0,0 до 1,0.
Чтобы завершить, удалите речевой профиль.
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'
Нет ответа.
Проверка, не зависящая от текста
Проверка, не зависящая от текста, отличается от проверки, зависящей от текста, в следующих аспектах.
- Определенная парольная фраза не требуется, можно произносить что угодно.
- Не требуются три примера звуковых данных, но требуется, чтобы длительность звуковых данных составляла 20 секунд.
Начните с создания профиля проверки, не зависящего от текста.
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'\''
}'
Вы получите следующий ответ:
{
"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,
}
Затем зарегистрируете речевой профиль. Опять же, вместо отправки трех примеров звуковых данных необходимо отправить только те примеры, длительность звуковых данных которых составляет 20 секунд.
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'
Отправив достаточное количество примеров звуковых данных, вы получите следующий ответ:
{
"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
}
Теперь вы готовы сверить пример звуковых данных с речевым профилем. Опять же, этот пример звуковых данных не обязательно должен содержать парольную фразу. Он может содержать любое речевое сопровождение, однако в целом длительность речи не может быть менее чем четыре секунды.
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'
Вы получите следующий ответ:
{
"recognitionResult": "Accept",
"score": 0.9196669459342957
}
Accept
означает, что проверка прошла успешно. Ответ также содержит показатель подобия в диапазоне от 0,0 до 1,0.
Чтобы завершить, удалите речевой профиль.
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'
Нет ответа.
Идентификация говорящего
Идентификация говорящего используется для определения, кто именно говорит из определенной группы зарегистрированных голосов. Этот процесс похож на проверку, не зависящую от текста. Основное отличие заключается в том, что можно сравнивать не с одним, а сразу с несколькими речевыми профилями.
Начните с создания профиля идентификации, не зависящего от текста.
# 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'\''
}'
Вы получите следующий ответ:
{
"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
}
Затем вам нужно зарегистрировать речевой профиль. Опять же, вам необходимо отправить примеры звуковых данных, длительность которых составляет 20 секунд. Эти примеры не обязательно должны содержать парольную фразу.
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'
Отправив достаточное количество примеров звуковых данных, вы получите следующий ответ:
{
"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
}
Теперь все готово к определению примера звуковых данных с помощью речевого профиля. Команда определения принимает список возможных идентификаторов речевых профилей, разделенных запятыми. В этом случае вы передадите идентификатор созданного ранее речевого профиля. При необходимости можно передать несколько идентификаторов речевого профиля, каждый из которых зарегистрирован с помощью примеров звуковых данных другого голоса.
# 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'
Вы получите следующий ответ:
Success:
{
"identifiedProfile": {
"profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
"score": 0.9083486
},
"profilesRanking": [
{
"profileId": "de99ab38-36c8-4b82-b137-510907c61fe8",
"score": 0.9083486
}
]
}
Ответ содержит идентификатор речевого профиля, который наиболее полно соответствует отправленному примеру звуковых данных. Он также содержит список потенциальных речевых профилей, упорядоченных в порядке сходства.
Чтобы завершить, удалите речевой профиль.
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'
Нет ответа.
CLI службы "Речь" поддерживает распознавание говорящего, но мы еще не включили в эту статью руководство по использованию CLI. Выберите другой язык программирования, чтобы приступить к работе и ознакомиться с основными понятиями.