Mulai cepat: Mengenali dan memverifikasi siapa yang berbicara

Dokumentasi referensi | Paket (NuGet) | Sampel Tambahan pada GitHub

Dalam mulai cepat ini, Anda akan mempelajari pola desain dasar untuk Pengenalan Pembicara menggunakan SDK Speech, seperti:

  • Verifikasi terikat teks dan bebas teks.
  • Identifikasi pembicara untuk mengidentifikasi sampel suara di antara sekelompok suara.
  • Menghapus profil suara.

Untuk melihat konsep Speaker Recognition tingkat tinggi, lihat artikel gambaran umum. Lihat node Referensi di panel kiri untuk daftar platform yang didukung.

Penting

Microsoft membatasi akses ke pengenalan speaker. Terapkan untuk menggunakannya melalui formulir Tinjauan Akses Terbatas Pengenalan Speaker Azure AI . Setelah persetujuan, Anda dapat mengakses API Pengenalan Pembicara.

Prasyarat

Menginstal Speech SDK

Sebelum memulai, Anda harus memasang Speech SDK. Bergantung pada platform Anda, gunakan instruksi berikut:

Mengimpor dependensi

Untuk menjalankan contoh dalam artikel ini, sertakan pernyataan using berikut di bagian atas skrip Anda:

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

Membuat konfigurasi ucapan

Untuk memanggil layanan Azure Cognitive Service untuk Ucapan dengan menggunakan Speech SDK, Anda perlu membuat instans SpeechConfig. Dalam contoh ini, Anda membuat instans SpeechConfig menggunakan kunci dan wilayah langganan. Anda juga membuat beberapa kode boilerplate dasar untuk digunakan pada sisa artikel ini, yang diubah untuk penyesuaian yang berbeda.

Penting

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan cara aman menyimpan dan mengakses informasi masuk Anda seperti Azure Key Vault. Lihat artikel keamanan layanan Azure AI untuk informasi selengkapnya.

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

Verifikasi tergantung teks

Verifikasi Pembicara adalah tindakan mengonfirmasi bahwa pembicara cocok dengan suara yang dikenal atau terdaftar. Langkah pertama adalah mendaftarkan profil suara sehingga layanan memiliki suara untuk dibandingkan dengan sampel suara selanjutnya. Dalam contoh ini, Anda mendaftarkan profil menggunakan strategi terikat teks yang memerlukan frasa sandi tertentu untuk digunakan mendaftar dan memverifikasi. Lihat dokumen referensi untuk daftar frasa sandi yang didukung.

Mulailah dengan membuat fungsi berikut di kelas Program Anda untuk mendaftarkan profil suara:

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

Dalam fungsi ini, await client.CreateProfileAsync() merupakan elemen yang benar-benar membuat profil suara baru. Setelah dibuat, Anda menentukan cara memasukkan sampel audio menggunakan AudioConfig.FromDefaultMicrophoneInput()dalam contoh ini untuk mengambil audio dari perangkat input default Anda. Selanjutnya, Anda mendaftarkan sampel audio dalam perulangan while yang melacak jumlah sampel yang tersisa dan diperlukan untuk mendaftar. Dalam setiap perulangan, client.EnrollProfileAsync(profile, audioInput) meminta Anda untuk mengucapkan frasa sandi ke mikrofon, dan menambahkan sampel ke profil suara.

Setelah pendaftaran selesai, Anda akan memanggil await SpeakerVerify(config, profile, profileMapping) untuk memverifikasi profil yang baru saja dibuat. Tambahkan fungsi lain untuk menentukan 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}");
}

Dalam fungsi ini, Anda meneruskan objek VoiceProfile yang baru saja dibuat untuk menginisialisasi model untuk diverifikasi. Selanjutnya, await speakerRecognizer.RecognizeOnceAsync(model) meminta Anda untuk mengucapkan frase sandi lagi. Kali ini memvalidasinya terhadap profil suara Anda dan mengembalikan skor kesamaan yang berkisar dari 0,0 hingga 1,0. Objek result juga mengembalikan Accept atau Reject, berdasarkan apakah frase sandi sesuai atau tidak.

Selanjutnya, ubah fungsi Main() untuk memanggil fungsi baru yang telah dibuat. Selain itu, perhatikan bahwa Anda membuat Dictionary<string, string> untuk meneruskan referensi melalui panggilan fungsi Anda. Alasan hal ini ialah karena layanan tidak memungkinkan menyimpan nama yang dapat dibaca manusia dengan VoiceProfile yang dibuat, dan hanya menyimpan nomor ID untuk tujuan privasi. Dalam fungsi VerificationEnroll, Anda menambahkan entri ke kamus ini dengan ID yang baru dibuat, bersama dengan nama teks. Dalam skenario pengembangan aplikasi tempat Anda harus menampilkan nama yang dapat dibaca manusia, Anda harus menyimpan pemetaan ini di suatu tempat di mana layanan tidak dapat menyimpannya.

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

Jalankan skrip. Jalankan skrip, dan Anda diminta untuk mengucapkan frasa "Suara saya adalah paspor saya, verifikasi saya" tiga kali untuk mendaftar, dan satu waktu tambahan untuk memverifikasi. Hasil yang ditampilkan adalah skor kesamaan yang dapat Anda gunakan untuk membuat ambang batas kustom Anda sendiri untuk verifikasi.

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

Verifikasi bebas teks

Berbeda dengan verifikasi yang bergantung pada teks, verifikasi teks-independen tidak memerlukan tiga sampel audio, tetapi memang membutuhkan 20 detik total audio.

Buat beberapa perubahan sederhana pada fungsi VerificationEnroll Anda untuk beralih ke verifikasi bebas teks. Pertama, Anda mengubah jenis verifikasi menjadi VoiceProfileType.TextIndependentVerification. Selanjutnya, ubah loop while untuk melacak result.RemainingEnrollmentsSpeechLength yang akan terus meminta Anda untuk berbicara sampai 20 detik audio yang telah direkam.

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

Jalankan program lagi, dan skor kesamaan dikembalikan.

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

Identifikasi pembicara

Identifikasi Pembicara digunakan untuk menentukan siapa yang berbicara dari sekelompok suara tertentu yang terdaftar. Prosesnya mirip dengan verifikasi teks independen. Perbedaan utamanya adalah kemampuannya untuk memverifikasi beberapa profil suara sekaligus daripada memverifikasinya satu-satu.

Buat fungsi IdentificationEnroll untuk mendaftarkan beberapa profil suara. Proses pendaftaran untuk setiap profil sama dengan proses pendaftaran untuk verifikasi teks-independen. Proses ini membutuhkan 20 detik audio untuk setiap profil. Fungsi ini menerima daftar string profileNames, dan akan membuat profil suara baru untuk setiap nama dalam daftar. Fungsi ini menampilkan daftar objek VoiceProfile yang Anda gunakan di fungsi berikutnya untuk mengidentifikasi pembicara.

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

Buat fungsi SpeakerIdentification berikut untuk mengirimkan permintaan identifikasi. Perbedaan utama dalam fungsi ini dibandingkan dengan permintaan verifikasi pembicara adalah penggunaan SpeakerIdentificationModel.FromProfiles() yang menerima daftar objek 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}");
}

Ubah fungsi Main() Anda menjadi berikut ini. Anda membuat daftar string profileNames yang Anda berikan ke fungsi IdentificationEnroll() Anda. Pembuatan string ini akan meminta Anda membuat profil suara baru untuk setiap nama dalam daftar ini sehingga Anda dapat menambahkan lebih banyak nama untuk membuat profil tambahan untuk teman atau kolega.

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

Jalankan skrip. Anda diminta berbicara untuk mendaftarkan sampel suara profil pertama. Setelah pendaftaran selesai, Anda diminta untuk mengulangi proses ini untuk setiap nama dalam daftar profileNames. Setelah setiap pendaftaran selesai, Anda diminta untuk meminta siapa pun berbicara. Layanan ini kemudian mencoba mengidentifikasi orang ini dari antara profil suara Anda yang terdaftar.

Contoh ini hanya mengembalikan pertandingan terdekat dan skor kesamaannya. Untuk mendapatkan respons penuh yang mencakup lima skor kesamaan teratas, tambahkan string json = result.Properties.GetProperty(PropertyId.SpeechServiceResponse_JsonResult) ke fungsi Anda SpeakerIdentification.

Mengubah tipe input audio

Contoh dalam artikel ini menggunakan mikrofon perangkat default sebagai input sampel audio. Dalam skenario yang mengharuskan Anda menggunakan file audio, bukan input mikrofon, cukup ubah contoh AudioConfig.FromDefaultMicrophoneInput() menjadi AudioConfig.FromWavFileInput(path/to/your/file.wav) untuk beralih ke input file. Anda juga dapat memiliki input campuran menggunakan mikrofon untuk pendaftaran dan file untuk verifikasi, misalnya.

Menghapus pendaftaran profil suara

Untuk menghapus profil terdaftar, gunakan fungsi DeleteProfileAsync() pada objek VoiceProfileClient. Fungsi contoh berikut menunjukkan cara menghapus profil suara dari ID profil suara yang diketahui:

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

Dokumentasi referensi | Paket (NuGet) | Sampel Tambahan pada GitHub

Dalam mulai cepat ini, Anda akan mempelajari pola desain dasar untuk Pengenalan Pembicara menggunakan SDK Speech, seperti:

  • Verifikasi terikat teks dan bebas teks.
  • Identifikasi pembicara untuk mengidentifikasi sampel suara di antara sekelompok suara.
  • Menghapus profil suara.

Untuk melihat konsep Speaker Recognition tingkat tinggi, lihat artikel gambaran umum. Lihat node Referensi di panel kiri untuk daftar platform yang didukung.

Penting

Microsoft membatasi akses ke pengenalan speaker. Terapkan untuk menggunakannya melalui formulir Azure AI Speaker Recognition Limited Access Review . Setelah persetujuan, Anda dapat mengakses API Pengenalan Pembicara.

Prasyarat

Menginstal Speech SDK

Sebelum memulai, Anda harus memasang Speech SDK. Bergantung pada platform Anda, gunakan instruksi berikut:

Mengimpor dependensi

Untuk menjalankan contoh dalam artikel ini, tambahkan pernyataan berikut di bagian atas file .cpp Anda:

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

Membuat konfigurasi ucapan

Untuk memanggil layanan Azure Cognitive Service untuk Ucapan dengan menggunakan Speech SDK, buat kelas SpeechConfig. Kelas ini mencakup informasi tentang langganan Anda, seperti kunci dan wilayah terkait, titik akhir, host, atau token otorisasi.

Penting

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan cara aman menyimpan dan mengakses informasi masuk Anda seperti Azure Key Vault. Lihat artikel keamanan layanan Azure AI untuk informasi selengkapnya.

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

Verifikasi tergantung teks

Verifikasi Pembicara adalah tindakan mengonfirmasi bahwa pembicara cocok dengan suara yang dikenal atau terdaftar. Langkah pertama adalah mendaftarkan profil suara sehingga layanan memiliki suara untuk dibandingkan dengan sampel suara selanjutnya. Dalam contoh ini, Anda mendaftarkan profil menggunakan strategi terikat teks yang memerlukan frasa sandi tertentu untuk digunakan mendaftar dan memverifikasi. Lihat dokumen referensi untuk daftar frasa sandi yang didukung.

Fungsi TextDependentVerification

Mulailah dengan membuat fungsi 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);
}

Fungsi ini membuat objek VoiceProfile dengan metode CreateProfileAsync. Terdapat tiga jenisVoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

Dalam hal ini, Anda meneruskan VoiceProfileType::TextDependentVerification ke CreateProfileAsync.

Selanjutnya Anda akan memanggil dua fungsi bantuan yang akan ditentukan berikutnya, AddEnrollmentsToTextDependentProfile dan SpeakerVerify. Terakhir, panggil DeleteProfileAsync untuk membersihkan profil.

Fungsi AddEnrollmentsToTextDependentProfile

Tentukan fungsi berikut untuk mendaftarkan profil suara:

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

Dalam fungsi ini, Anda mendaftarkan sampel audio while dalam perulangan yang melacak jumlah sampel yang tersisa, dan diperlukan, untuk pendaftaran. Dalam setiap perulangan, EnrollProfileAsync meminta Anda untuk mengucapkan frasa sandi ke mikrofon, dan menambahkan sampel ke profil suara.

Fungsi SpeakerVerify

Tentukan SpeakerVerify sebagai berikut:

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

Dalam fungsi ini, Anda akan membuat objek SpeakerVerificationModel dengan metode SpeakerVerificationModel.FromProfile, meneruskan objek VoiceProfile yang telah dibuat sebelumnya.

Selanjutnya, SpeechRecognizer:RecognizeOnceAsync meminta Anda untuk mengucap frase sandi lagi. Kali ini memvalidasinya terhadap profil suara Anda dan mengembalikan skor kesamaan yang berkisar dari 0,0 hingga 1,0. Objek SpeakerRecognitionResult juga mengembalikan Accept atau Reject, berdasarkan apakah frase sandi sesuai atau tidak.

Verifikasi tak tergantung teks

Berbeda dengan verifikasi yang bergantung pada teks, verifikasi teks-independen tidak memerlukan tiga sampel audio, tetapi memang membutuhkan 20 detik total audio.

Fungsi TextIndependentVerification

Mulailah dengan membuat fungsi 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);
}

Seperti fungsi TextDependentVerification, fungsi ini membuat objek VoiceProfile dengan metode CreateProfileAsync.

Dalam hal ini, Anda meneruskan VoiceProfileType::TextIndependentVerification ke CreateProfileAsync.

Anda kemudian memanggil dua fungsi bantuan: fungsi AddEnrollmentsToTextIndependentProfile yang akan ditentukan berikutnya dan fungsi SpeakerVerify yang sudah ditentukan. Terakhir, panggil DeleteProfileAsync untuk membersihkan profil.

AddEnrollmentsToTextIndependentProfile

Tentukan fungsi berikut untuk mendaftarkan profil suara:

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

Dalam fungsi ini, Anda mendaftarkan sampel audio while dalam perulangan yang melacak jumlah detik audio yang tersisa, dan diperlukan, untuk pendaftaran. Dalam setiap perulangan, EnrollProfileAsync meminta Anda untuk berbicara ke mikrofon, dan menambahkan sampel ke profil suara.

Identifikasi pembicara

Identifikasi Pembicara digunakan untuk menentukan siapa yang berbicara dari sekelompok suara tertentu yang terdaftar. Prosesnya mirip dengan verifikasi teks independen. Perbedaan utamanya adalah kemampuannya untuk memverifikasi beberapa profil suara sekaligus daripada memverifikasinya satu-satu.

Fungsi TextIndependentIdentification

Mulailah dengan membuat fungsi 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);
}

Seperti TextDependentVerification dan fungsi TextIndependentVerification, fungsi ini membuat objek VoiceProfile dengan metode CreateProfileAsync.

Dalam hal ini, Anda meneruskan VoiceProfileType::TextIndependentIdentification ke CreateProfileAsync.

Anda kemudian memanggil dua fungsi bantuan: fungsi AddEnrollmentsToTextIndependentProfile yang sudah ditentukan dan fungsi SpeakerIdentify yang akan ditentukan berikutnya. Terakhir, panggil DeleteProfileAsync untuk membersihkan profil.

Fungsi SpeakerIdentify

Tentukan fungsi SpeakerIdentify sebagai berikut:

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

Dalam fungsi ini, Anda membuat objek SpeakerIdentificationModel dengan metode SpeakerIdentificationModel::FromProfiles. SpeakerIdentificationModel::FromProfiles menerima daftar objek VoiceProfile. Dalam hal ini, Anda hanya akan meneruskan objek VoiceProfile yang dibuat sebelumnya. Namun, jika mau, Anda dapat meneruskan beberapa objek VoiceProfile, masing-masing terdaftar dengan sampel audio dari suara yang berbeda.

Selanjutnya, SpeechRecognizer::RecognizeOnceAsync meminta Anda untuk berbicara lagi. Kali ini membandingkan suara Anda dengan profil suara terdaftar dan mengembalikan profil suara yang paling mirip.

Fungsi utama

Terakhir, tentukan fungsi main sebagai berikut:

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

Fungsi ini hanya memanggil fungsi yang Anda tentukan sebelumnya. Namun, pertama-tama, fungsi tersebut membuat objek VoiceProfileClient dan objek SpeakerRecognizer.

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

Objek VoiceProfileClient digunakan untuk membuat, mendaftarkan, dan menghapus profil suara. Objek SpeakerRecognizer digunakan untuk memvalidasi sampel ucapan terhadap satu atau beberapa profil suara terdaftar.

Mengubah tipe input audio

Contoh dalam artikel ini menggunakan mikrofon perangkat default sebagai input sampel audio. Namun, dalam skenario yang mengharuskan Anda menggunakan file audio alih-alih input mikrofon, cukup ubah baris berikut:

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

ke:

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

Atau ganti penggunaan audio_config dengan Audio::AudioConfig::FromWavFileInput. Anda juga dapat memiliki input campuran menggunakan mikrofon untuk pendaftaran dan file untuk verifikasi, misalnya.

Dokumentasi referensi | Paket (Go) | Sampel Tambahan pada GitHub

Dalam mulai cepat ini, Anda akan mempelajari pola desain dasar untuk Pengenalan Pembicara menggunakan SDK Speech, seperti:

  • Verifikasi terikat teks dan bebas teks.
  • Identifikasi pembicara untuk mengidentifikasi sampel suara di antara sekelompok suara.
  • Menghapus profil suara.

Untuk melihat konsep Speaker Recognition tingkat tinggi, lihat artikel gambaran umum. Lihat node Referensi di panel kiri untuk daftar platform yang didukung.

Penting

Microsoft membatasi akses ke pengenalan speaker. Terapkan untuk menggunakannya melalui formulir Azure AI Speaker Recognition Limited Access Review . Setelah persetujuan, Anda dapat mengakses API Pengenalan Pembicara.

Prasyarat

Menyiapkan lingkungan

Pasang Speech SDK untuk Go. Periksa Panduan penginstalan SDK untuk persyaratan lainnya

Melakukan identifikasi independen

Ikuti langkah-langkah ini untuk membuat modul GO baru.

  1. Buka perintah di mana Anda menginginkan modul baru, dan buat file baru bernama independent-identification.go.

  2. Ganti isi independent-identification.go dengan kode berikut.

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

    Penting

    Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan cara aman menyimpan dan mengakses informasi masuk Anda seperti Azure Key Vault. Lihat artikel keamanan layanan Azure AI untuk informasi selengkapnya.

Jalankan perintah berikut untuk membuat file go.mod yang ditautkan ke komponen yang dihosting di GitHub:

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

Sekarang, bangun dan jalankan kode:

go build
go run independent-identification

Melakukan verifikasi independen

Ikuti langkah-langkah ini untuk membuat modul GO baru.

  1. Buka perintah di mana Anda menginginkan modul baru, dan buat file baru bernama independent-verification.go.

  2. Ganti isi independent-verification.go dengan kode berikut.

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

Jalankan perintah berikut untuk membuat file go.mod yang ditautkan ke komponen yang dihosting di GitHub:

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

Sekarang, bangun dan jalankan kode:

go build
go run independent-verification

Membersihkan sumber daya

Anda dapat menggunakan portal Azure atau Azure Command Line Interface (CLI) untuk menghapus sumber daya Ucapan yang Anda buat.

Dokumentasi referensi | Sampel Tambahan pada GitHub

Speech SDK for Java memang mendukung pengenalan pembicara, tetapi kami belum menyertakan panduan di sini. Silakan pilih bahasa pemrograman lain untuk memulai dan belajar tentang konsep, atau lihat referensi Java dan sampel yang ditautkan dari awal artikel ini.

Dokumentasi referensi | Paket (npm) | Sampel Tambahan pada kode sumber GitHub | Library

Dalam mulai cepat ini, Anda akan mempelajari pola desain dasar untuk Pengenalan Pembicara menggunakan SDK Speech, seperti:

  • Verifikasi terikat teks dan bebas teks.
  • Identifikasi pembicara untuk mengidentifikasi sampel suara di antara sekelompok suara.
  • Menghapus profil suara.

Untuk melihat konsep Speaker Recognition tingkat tinggi, lihat artikel gambaran umum. Lihat node Referensi di panel kiri untuk daftar platform yang didukung.

Penting

Microsoft membatasi akses ke pengenalan speaker. Terapkan untuk menggunakannya melalui formulir Azure AI Speaker Recognition Limited Access Review . Setelah persetujuan, Anda dapat mengakses API Pengenalan Pembicara.

Prasyarat

Menginstal Speech SDK

Sebelum memulai, Anda harus menginstal Speech SDK untuk JavaScript .

Selain itu, bergantung pada lingkungan target, gunakan salah satu hal berikut ini:

Unduh dan ekstrak Speech SDK for JavaScript file microsoft.cognitiveservices.speech.sdk.bundle.js. Tempatkan di folder yang dapat diakses oleh file HTML Anda.

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

Tip

Jika Anda menargetkan browser web, dan menggunakan tag <script> awalan sdk tidak diperlukan. Awalan sdk adalah alias yang digunakan untuk memberi nama modul require.

Mengimpor dependensi

Untuk menjalankan contoh dalam artikel ini, tambahkan pernyataan berikut di bagian atas file .js Anda:

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

Pernyataan ini mengimpor pustaka yang diperlukan dan mendapatkan kunci dan wilayah langganan layanan Speech dari variabel lingkungan Anda. Pernyataan tersebut juga menentukan jalur ke file audio yang akan Anda gunakan dalam tugas berikut.

Penting

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan cara aman menyimpan dan mengakses informasi masuk Anda seperti Azure Key Vault. Lihat artikel keamanan layanan Azure AI untuk informasi selengkapnya.

Membuat fungsi bantuan

Tambahkan fungsi bantuan berikut untuk membaca file audio ke dalam aliran untuk digunakan oleh layanan Speech:

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

Dalam fungsi ini, Anda menggunakan metode AudioInputStream.createPushStream dan AudioConfig.fromStreamInput untuk membuat objek AudioConfig. Objek AudioConfig ini mewakili aliran audio. Anda akan menggunakan beberapa objek AudioConfig ini selama tugas berikut.

Verifikasi tergantung teks

Verifikasi Pembicara adalah tindakan mengonfirmasi bahwa pembicara cocok dengan suara yang dikenal atau terdaftar. Langkah pertama adalah mendaftarkan profil suara sehingga layanan memiliki suara untuk dibandingkan dengan sampel suara selanjutnya. Dalam contoh ini, Anda mendaftarkan profil menggunakan strategi terikat teks yang memerlukan frasa sandi tertentu untuk digunakan mendaftar dan memverifikasi. Lihat dokumen referensi untuk daftar frasa sandi yang didukung.

Fungsi TextDependentVerification

Mulailah dengan membuat fungsi 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);
        }
    }
}

Fungsi ini membuat objek VoiceProfile dengan metode VoiceProfileClient.createProfileAsync. Terdapat tiga jenisVoiceProfile:

  • TextIndependentIdentification
  • TextDependentVerification
  • TextIndependentVerification

Dalam hal ini, Anda meneruskan VoiceProfileType.TextDependentVerification ke VoiceProfileClient.createProfileAsync.

Selanjutnya Anda akan memanggil dua fungsi bantuan yang akan ditentukan berikutnya, AddEnrollmentsToTextDependentProfile dan SpeakerVerify. Terakhir, panggil VoiceProfileClient.deleteProfileAsync untuk menghapus profil.

Fungsi AddEnrollmentsToTextDependentProfile

Tentukan fungsi berikut untuk mendaftarkan profil suara:

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

Dalam fungsi ini, Anda memanggil GetAudioConfigFromFile fungsi yang telah ditentukan sebelumnya untuk membuat objek AudioConfig dari sampel audio. Sampel audio ini berisi frase sandi, seperti "Suara saya adalah paspor saya, verifikasi saya." Anda kemudian mendaftarkan sampel audio ini dengan menggunakan metode VoiceProfileClient.enrollProfileAsync.

Fungsi SpeakerVerify

Tentukan SpeakerVerify sebagai berikut:

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

Dalam fungsi ini, Anda akan membuat objek SpeakerVerificationModel dengan metode SpeakerVerificationModel.FromProfile, meneruskan objek VoiceProfile yang telah dibuat sebelumnya.

Selanjutnya, Anda memanggil metode SpeechRecognizer.recognizeOnceAsync untuk memvalidasi sampel audio yang berisi frasa sandi yang sama dengan sampel audio yang didaftarkan sebelumnya. SpeechRecognizer.recognizeOnceAsync mengembalikan objek SpeakerRecognitionResult, yang propertinya score berisi skor kesamaan yang berkisar antara 0,0 hingga 1,0. Objek SpeakerRecognitionResult juga berisi properti reason tipe ResultReason. Jika verifikasi berhasil, properti reason harus memiliki nilai RecognizedSpeaker.

Verifikasi bebas teks

Berbeda dengan verifikasi terikat teks, verifikasi bebas teks:

  • Tidak membutuhkan frase sandi tertentu untuk diucapkan. Apa pun bisa diucapkan.
  • Tidak memerlukan tiga sampel audio, tetapi memerlukan 20 detik dari total audio.

Fungsi TextIndependentVerification

Mulailah dengan membuat fungsi 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);
        }
    }
}

Seperti fungsi TextDependentVerification, fungsi ini membuat objek VoiceProfile dengan metode VoiceProfileClient.createProfileAsync.

Dalam hal ini, Anda meneruskan VoiceProfileType.TextIndependentVerification ke createProfileAsync.

Anda kemudian memanggil dua fungsi bantuan: fungsi AddEnrollmentsToTextIndependentProfile yang akan ditentukan berikutnya dan fungsi SpeakerVerify yang sudah ditentukan. Terakhir, panggil VoiceProfileClient.deleteProfileAsync untuk menghapus profil.

AddEnrollmentsToTextIndependentProfile

Tentukan fungsi berikut untuk mendaftarkan profil suara:

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

Dalam fungsi ini, Anda memanggil GetAudioConfigFromFile fungsi yang telah ditentukan sebelumnya untuk membuat objek AudioConfig dari sampel audio. Kemudian Anda mendaftarkan sampel audio ini menggunakan metode VoiceProfileClient.enrollProfileAsync.

Identifikasi pembicara

Identifikasi Pembicara digunakan untuk menentukan siapa yang berbicara dari sekelompok suara tertentu yang terdaftar. Prosesnya mirip dengan verifikasi teks independen. Perbedaan utamanya adalah kemampuannya untuk memverifikasi beberapa profil suara sekaligus daripada memverifikasinya satu-satu.

Fungsi TextIndependentIdentification

Mulailah dengan membuat fungsi 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);
        }
    }
}

Seperti fungsi TextDependentVerification dan TextIndependentVerification, fungsi ini membuat objek VoiceProfile dengan metode VoiceProfileClient.createProfileAsync.

Dalam hal ini, Anda meneruskan VoiceProfileType.TextIndependentIdentification ke VoiceProfileClient.createProfileAsync.

Anda kemudian memanggil dua fungsi bantuan: fungsi AddEnrollmentsToTextIndependentProfile yang sudah ditentukan dan fungsi SpeakerIdentify yang akan ditentukan berikutnya. Terakhir, panggil VoiceProfileClient.deleteProfileAsync untuk menghapus profil.

Fungsi SpeakerIdentify

Tentukan fungsi SpeakerIdentify sebagai berikut:

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

Dalam fungsi ini, Anda akan membuat objek SpeakerIdentificationModel dengan metode SpeakerIdentificationModel.fromProfiles yang meneruskan objek VoiceProfile yang telah dibuat sebelumnya.

Selanjutnya, Anda memanggil metode SpeechRecognizer.recognizeOnceAsync dan meneruskan sampel audio. SpeechRecognizer.recognizeOnceAsync mencoba mengidentifikasi suara untuk sampel audio ini berdasarkan objek VoiceProfile yang Anda gunakan untuk membuat SpeakerIdentificationModel. Langkah in akan menampilkan objek SpeakerRecognitionResult yang properti profileId-nya mengidentifikasi kecocokan VoiceProfile, jika ada, sementara properti score berisi skor kesamaan antara 0,0 hingga 1,0.

Fungsi utama

Terakhir, tentukan fungsi main sebagai berikut:

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

Fungsi ini membuat objek VoiceProfileClient, yang digunakan untuk membuat, mendaftarkan, dan menghapus profil suara. Kemudian memanggil fungsi yang Anda tentukan sebelumnya.

Dokumentasi referensi | Paket (Unduh) | Sampel Tambahan pada GitHub

Speech SDK untuk Objective-C tidak mendukung pengenalan pembicara. Silakan pilih bahasa pemrograman lain atau referensi Objective-C dan sampel yang ditautkan dari awal artikel ini.

Dokumentasi referensi | Paket (Unduh) | Sampel Tambahan pada GitHub

Speech SDK untuk Swift tidak mendukung pengenalan pembicara. Silakan pilih bahasa pemrograman lain atau referensi Swift dan sampel yang ditautkan dari awal artikel ini.

Dokumentasi referensi | Paket (PyPi) | Sampel Tambahan pada GitHub

Speech SDK untuk Python tidak mendukung pengenalan pembicara. Silakan pilih bahasa pemrograman lain atau referensi Python dan sampel yang ditautkan dari awal artikel ini.

Referensi | REST API ucapan ke teksREST API ucapan ke teks untuk referensi | audio pendekSampel Tambahan di GitHub

Dalam mulai cepat ini, Anda akan mempelajari pola desain dasar untuk Pengenalan Pembicara menggunakan SDK Speech, seperti:

  • Verifikasi terikat teks dan bebas teks.
  • Identifikasi pembicara untuk mengidentifikasi sampel suara di antara sekelompok suara.
  • Menghapus profil suara.

Untuk melihat konsep Speaker Recognition tingkat tinggi, lihat artikel gambaran umum. Lihat node Referensi di panel kiri untuk daftar platform yang didukung.

Penting

Microsoft membatasi akses ke pengenalan speaker. Terapkan untuk menggunakannya melalui formulir Tinjauan Akses Terbatas Pengenalan Speaker Azure AI . Setelah persetujuan, Anda dapat mengakses API Pengenalan Pembicara.

Prasyarat

Verifikasi tergantung teks

Verifikasi Pembicara adalah tindakan mengonfirmasi bahwa pembicara cocok dengan suara yang dikenal atau terdaftar. Langkah pertama adalah mendaftarkan profil suara sehingga layanan memiliki suara untuk dibandingkan dengan sampel suara selanjutnya. Dalam contoh ini, Anda mendaftarkan profil menggunakan strategi terikat teks yang memerlukan frasa sandi tertentu untuk digunakan mendaftar dan memverifikasi. Lihat dokumen referensi untuk daftar frasa sandi yang didukung.

Mulailah dengan membuat profil suara. Anda harus menyisipkan kunci dan kawasan langganan layanan Ucapan Anda ke dalam setiap perintah curl dalam artikel ini.

Penting

Ingatlah untuk menghapus kunci dari kode Anda setelah selesai, dan jangan pernah memposting kode secara publik. Untuk produksi, gunakan cara aman menyimpan dan mengakses informasi masuk Anda seperti Azure Key Vault. Lihat artikel keamanan layanan Azure AI untuk informasi selengkapnya.

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

Perhatikan bahwa ada tiga jenis profil suara:

  • Verifikasi tergantung teks
  • Verifikasi tak tergantung teks
  • Identifikasi independen teks

Dalam hal ini, Anda membuat profil suara verifikasi yang bergantung pada teks. Seharusnya Anda akan menerima respons berikut:

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

Selanjutnya, Anda mendaftarkan profil suara. --data-binary Untuk nilai parameter, tentukan file audio di komputer Anda yang berisi salah satu frasa sandi yang didukung, seperti "Suara saya adalah paspor saya, verifikasi saya." Anda dapat merekam file audio dengan aplikasi seperti Perekam Windows Voice. Atau Anda dapat membuatnya dengan menggunakan teks ke ucapan.

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'

Seharusnya Anda akan menerima respons berikut:

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

Respons ini memberi tahu Anda bahwa Anda perlu mendaftarkan dua sampel audio lagi.

Setelah Anda mendaftarkan total tiga sampel audio, Anda harus menerima respons berikut:

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

Sekarang Anda siap untuk memverifikasi sampel audio terhadap profil suara. Sampel audio ini harus berisi frasa sandi yang sama dengan sampel yang Anda gunakan untuk mendaftarkan profil suara.

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'

Seharusnya Anda akan menerima respons berikut:

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

Accept berarti frase sandi cocok dan verifikasi berhasil. Respons juga berisi skor kesamaan yang berkisar antara 0,0 hingga 1,0.

Untuk menyelesaikannya, hapus profil suara.

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'

Tidak ada jawaban.

Verifikasi bebas teks

Berbeda dengan verifikasi terikat teks, verifikasi bebas teks:

  • Tidak membutuhkan frase sandi tertentu untuk diucapkan. Apa pun bisa diucapkan.
  • Tidak memerlukan tiga sampel audio, tetapi memerlukan 20 detik dari total audio.

Mulailah dengan membuat profil verifikasi independen teks.

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

Seharusnya Anda akan menerima respons berikut:

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

Selanjutnya, daftarkan profil suara. Sekali lagi, daripada mengirimkan tiga sampel audio, Anda perlu mengirimkan sampel audio yang berisi total 20 detik audio.

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

Setelah Anda mengirimkan sampel audio yang cukup, seharusnya Anda akan menerima respons berikut:

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

Sekarang Anda siap untuk memverifikasi sampel audio terhadap profil suara. Sekali lagi, sampel audio ini tidak perlu berisi frasa sandi. Ini dapat berisi ucapan apa pun, selama berisi total setidaknya empat detik audio.

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

Seharusnya Anda akan menerima respons berikut:

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

Accept berarti verifikasi berhasil. Respons juga berisi skor kesamaan yang berkisar antara 0,0 hingga 1,0.

Untuk menyelesaikannya, hapus profil suara.

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'

Tidak ada jawaban.

Identifikasi pembicara

Identifikasi Pembicara digunakan untuk menentukan siapa yang berbicara dari sekelompok suara tertentu yang terdaftar. Prosesnya mirip dengan verifikasi teks independen. Perbedaan utamanya adalah kemampuannya untuk memverifikasi beberapa profil suara sekaligus daripada memverifikasinya satu-satu.

Mulailah dengan membuat profil identifikasi independen teks.

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

Seharusnya Anda akan menerima respons berikut:

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

Selanjutnya, Anda mendaftarkan profil suara. Sekali lagi, Anda perlu mengirimkan sampel audio yang berisi total 20 detik audio. Sampel ini tidak perlu berisi frase sandi.

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'

Setelah Anda mengirimkan sampel audio yang cukup, seharusnya Anda akan menerima respons berikut:

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

Sekarang Anda siap untuk mengidentifikasi sampel audio menggunakan profil suara. Perintah identifikasi menerima daftar koma yang dibatasi dari kemungkinan ID profil suara. Dalam hal ini, Anda hanya akan meneruskan ID profil suara yang Anda buat sebelumnya. Namun, jika mau, Anda dapat meneruskan beberapa ID profil suara di mana setiap profil suara didaftarkan dengan sampel audio dari suara yang berbeda.

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

Seharusnya Anda akan menerima respons berikut:

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

Respons berisi ID profil suara yang paling cocok dengan sampel audio yang Anda kirimkan. Ini juga berisi daftar profil suara kandidat, yang diberi peringkat dalam urutan kesamaan.

Untuk menyelesaikannya, hapus profil suara.

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'

Tidak ada jawaban.

Speech CLI memang mendukung pengenalan pembicara, tetapi kami belum menyertakan panduan di sini. Silakan pilih bahasa pemrograman lain untuk memulai dan belajar tentang konsep.

Langkah berikutnya

Lihat sampel mulai cepat di GitHub