التشغيل التسريع: تعرف على المتحدث وتحقق منه

حزمة الوثائق المرجعية | (NuGet) | عينات إضافية على GitHub

في هذا التشغيل السريع، تتعلم أنماط التصميم الأساسية للتعرف على المتحدث باستخدام Speech SDK، بما في ذلك:

  • التحقق المعتمد على النص والمستقل عن النص.
  • تحديد المتحدث لتحديد عينة صوتية بين مجموعة من الأصوات.
  • قم بحذف ملفات تعريف الصوت.

لإلقاء نظرة فاحصة على مفاهيم "Speech Recognition"، قم بمراجعة مقالة "overview". راجع العقدة المرجعية في الجزء الأيمن للحصول على قائمة بالأنظمة الأساسية المدعومة.

هام

تحد Microsoft من الوصول إلى التعرف على المتحدث. تطبيق لاستخدامه من خلال نموذج مراجعة الوصول المحدود للتعرف على المتحدث في Azure الذكاء الاصطناعي . بعد الموافقة، يمكنك الوصول إلى واجهات برمجة التطبيقات الخاصة بـSpeaker Recognition.

المتطلبات الأساسية

تثبيت Speech SDK

قبل أن تبدأ، يجب عليك تثبيت Speech SDK. اعتمادًا على النظام الأساسي الخاص بك، استخدم الإرشادات التالية:

استيراد التبعيات

لتشغيل الأمثلة الواردة في هذه المقالة، قم بتضمين العبارات التاليةusing في الجزء العلوي من النص البرمجي:

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

إنشاء تكوين الكلام

للاتصال بخدمة الكلام باستخدام Speech 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 verification

التحقق من المتحدث هو عملية تأكيد أن المتحدث يطابق صوتًا معروفًا أو مسجل . تتمثل الخطوة الأولى في تسجيل ملف تعريف صوتي بحيث يكون للخدمة شيء ما لمقارنة عينات الصوت المستقبلية به. في هذا المثال، تقوم بتسجيل ملف التعريف باستخدام إستراتيجية تعتمد على النص، والتي تتطلب عبارة مرور معينة لاستخدامها في التسجيل والتحقق. يُرجى الرجوع إلى مستندات المرجع للحصول على قائمة عبارات المرور المعتمدة.

ابدأ بإنشاء الدالة التالية في صفك 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

Speaker identification

يتم استخدام تعريف المتحدث لتحديد من يتحدث من مجموعة معينة من الأصوات المسجلة. تشبه هذه العملية التحقق المستقل عن النص . يتمثل الاختلاف الرئيسي في القدرة على التحقق من ملفات تعريف صوتية متعددة في وقت واحد بدلاً من التحقق من ملف تعريف واحد.

إنشاء دالة 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

في هذا التشغيل السريع، تتعلم أنماط التصميم الأساسية للتعرف على المتحدث باستخدام Speech SDK، بما في ذلك:

  • التحقق المعتمد على النص والمستقل عن النص.
  • تحديد المتحدث لتحديد عينة صوتية بين مجموعة من الأصوات.
  • قم بحذف ملفات تعريف الصوت.

لإلقاء نظرة فاحصة على مفاهيم "Speech Recognition"، قم بمراجعة مقالة "overview". راجع العقدة المرجعية في الجزء الأيمن للحصول على قائمة بالأنظمة الأساسية المدعومة.

هام

تحد Microsoft من الوصول إلى التعرف على المتحدث. طبق لاستخدامه من خلال نموذج مراجعة الوصول المحدود للتعرف على المتحدث في Azure الذكاء الاصطناعي . بعد الموافقة، يمكنك الوصول إلى واجهات برمجة التطبيقات الخاصة بـSpeaker Recognition.

المتطلبات الأساسية

تثبيت Speech SDK

قبل أن تبدأ، يجب عليك تثبيت Speech 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;

إنشاء تكوين الكلام

للاتصال بخدمة Speech باستخدام Speech 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 verification

التحقق من المتحدث هو عملية تأكيد أن المتحدث يطابق صوتًا معروفًا أو مسجل . تتمثل الخطوة الأولى في تسجيل ملف تعريف صوتي بحيث يكون للخدمة شيء ما لمقارنة عينات الصوت المستقبلية به. في هذا المثال، تقوم بتسجيل ملف التعريف باستخدام إستراتيجية تعتمد على النص، والتي تتطلب عبارة مرور معينة لاستخدامها في التسجيل والتحقق. يُرجى الرجوع إلى مستندات المرجع للحصول على قائمة عبارات المرور المعتمدة.

دالة 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»
  • التحقق من صحة النص المستقل

في هذه الحالة، تجتاز 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 بناءً على ما إذا كانت عبارة المرور متطابقة أم لا.

Text-independent verification

على النقيض من التحقق المعتمد على النص ، لا يتطلب التحقق من النص المستقل ثلاث عينات صوتية ولكن لا تتطلب 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 بالتحدث في الميكروفون ويضيف العينة إلى ملف تعريف الصوت.

Speaker identification

يتم استخدام تعريف المتحدث لتحديد من يتحدث من مجموعة معينة من الأصوات المسجلة. تشبه هذه العملية التحقق المستقل عن النص . يتمثل الاختلاف الرئيسي في القدرة على التحقق من ملفات تعريف صوتية متعددة في وقت واحد بدلاً من التحقق من ملف تعريف واحد.

دالة 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» باستخدام طريقة SpeakerVerificationModel::FromProfiles. SpeakerIdentificationModel::FromProfilesيقبل قائمة كائنات «VoiceProfile». في هذه الحالة، تقوم بتمرير الكائن VoiceProfile الذي قمت بإنشائه مسبقًا. إذا أردت، يمكنك تمرير عدة كائنات VoiceProfile، كل منها مسجل بنماذج صوتية من صوت مختلف.

التالي، يوجهك «SpeechRecognizer::RecognizeOnceAsync» بالتحدث مرة أخرى. هذه المرة يقارن صوتك بملفات الصوت المسجلة ويعيد الملف الصوتي الأكثر تشابهًا.

الدالة الرئيسية

أخيرًا، حدد دالة 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

في هذا التشغيل السريع، تتعلم أنماط التصميم الأساسية للتعرف على المتحدث باستخدام Speech SDK، بما في ذلك:

  • التحقق المعتمد على النص والمستقل عن النص.
  • تحديد المتحدث لتحديد عينة صوتية بين مجموعة من الأصوات.
  • قم بحذف ملفات تعريف الصوت.

لإلقاء نظرة فاحصة على مفاهيم "Speech Recognition"، قم بمراجعة مقالة "overview". راجع العقدة المرجعية في الجزء الأيمن للحصول على قائمة بالأنظمة الأساسية المدعومة.

هام

تحد Microsoft من الوصول إلى التعرف على المتحدث. طبق لاستخدامه من خلال نموذج مراجعة الوصول المحدود للتعرف على المتحدث في Azure الذكاء الاصطناعي . بعد الموافقة، يمكنك الوصول إلى واجهات برمجة التطبيقات الخاصة بـSpeaker Recognition.

المتطلبات الأساسية

إعداد البيئة

قم بتثبيت Speech SDK for Go . راجع دليل تثبيت SDK لمعرفة المزيد من المتطلبات

إجراء تحديد مستقل

قم بإتباع هذه الخطوات لإنشاء وحدة GO جديدة.

  1. افتح موجه الأوامر حيث تريد الوحدة الجديدة، وأنشئ ملفًا جديدًا باسم independent-identification.go.

  2. استبدل محتويات 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')
    }
    
  3. في 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 جديدة.

  1. قم بفتح موجه الأوامر حيث تريد الوحدة الجديدة، وأنشئ ملفًا جديدًا باسم independent-verification.go.

  2. استبدل محتويات 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')
    }
    
  3. في 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

تنظيف الموارد

يمكنك استخدام مدخل Microsoft Azure أو واجهة سطر أوامر Azure (CLI) لإزالة مورد الكلام الذي قمت بإنشائه.

وثائق مرجعية | نماذج إضافية على GitHub

يدعم Speech SDK لـ Java التعرف على المتحدث، لكننا لم نقم بتضمين دليل هنا بعد. يُرجى تحديد لغة برمجة أخرى للبدء والتعرف على المفاهيم، أو الاطلاع على مرجع Java والعينات المرتبطة من بداية هذه المقالة.

وثائق مرجعية | Package (npm) | عينات إضافية على GitHub | شفرة مصدر المكتبة

في هذا التشغيل السريع، تتعلم أنماط التصميم الأساسية للتعرف على المتحدث باستخدام Speech SDK، بما في ذلك:

  • التحقق المعتمد على النص والمستقل عن النص.
  • تحديد المتحدث لتحديد عينة صوتية بين مجموعة من الأصوات.
  • قم بحذف ملفات تعريف الصوت.

لإلقاء نظرة فاحصة على مفاهيم "Speech Recognition"، قم بمراجعة مقالة "overview". راجع العقدة المرجعية في الجزء الأيمن للحصول على قائمة بالأنظمة الأساسية المدعومة.

هام

تحد Microsoft من الوصول إلى التعرف على المتحدث. طبق لاستخدامه من خلال نموذج مراجعة الوصول المحدود للتعرف على المتحدث في Azure الذكاء الاصطناعي . بعد الموافقة، يمكنك الوصول إلى واجهات برمجة التطبيقات الخاصة بـSpeaker Recognition.

المتطلبات الأساسية

تثبيت Speech SDK

قبل أن تبدأ، يجب عليك تثبيت Speech SDK لـ JavaScript.

اعتمادًا على البيئة المستهدفة، استخدم أحد الخيارات التالية:

قم بتنزيل واستخراج ملف Speech SDK for 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;

تعمل هذه العبارات على استيراد المكتبات المطلوبة، والحصول على مفتاح اشتراكك في خدمة Speech والمنطقة من متغيرات بيئتك. كما أنها تحدد مسارات الملفات الصوتية التي ستستخدمها في المهام التالية.

هام

تذكر إزالة المفتاح من التعليمات البرمجية عند الانتهاء، وعدم نشره على الملأ مطلقًا. للإنتاج، استخدم طريقة آمنة لتخزين بيانات الاعتماد والوصول إليها مثل Azure Key Vault. راجع مقالة أمان خدمات Azure الذكاء الاصطناعي لمزيد من المعلومات.

قم بإنشاء دالة مساعدة

أضف الوظيفة المساعدة التالية لقراءة الملفات الصوتية في تدفقات لتستخدمها خدمة الكلام:

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

في هذه الدالة، يمكنك استخدام AudioInputStream.createPushStream وAudioConfig.fromStreamInput لإنشاء كائن AudioConfig. يمثل الكائن AudioConfig هذا دفق الصوت. ستستخدم العديد من هذه الكائنات البالغ عددها AudioConfig أثناء المهام التالية.

Text-dependent verification

التحقق من المتحدث هو عملية تأكيد أن المتحدث يطابق صوتًا معروفًا أو مسجل . تتمثل الخطوة الأولى في تسجيل ملف تعريف صوتي بحيث يكون للخدمة شيء ما لمقارنة عينات الصوت المستقبلية به. في هذا المثال، تقوم بتسجيل ملف التعريف باستخدام إستراتيجية تعتمد على النص، والتي تتطلب عبارة مرور معينة لاستخدامها في التسجيل والتحقق. يُرجى الرجوع إلى مستندات المرجع للحصول على قائمة عبارات المرور المعتمدة.

دالة 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»
  • التحقق من صحة النص المستقل

في هذه الحالة، تجتاز VoiceProfileType.TextDependentVerification إلى VoiceProfileClient.createProfileAsync.

ثم تستدعي دالتي مساعدة، لتحددهما لاحقا، AddEnrollmentsToTextDependentProfile وSpeakerVerify. وأخيرا، قم باستدعاء VoiceProfileClient.deleteProfileAsync لإزالة الملف التعريفي.

دالة إضافة التسجيلات إلى ملف التعريف للنص غير المستقل

حدد الدالة التالية من أجل تسجيل ملف تعريف صوتي:

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.

Text-independent verification

على عكس عملية text-dependent verificationتكون عملية text-independent verification كالآتي:

  • لا يتطلب نطق عبارة مرور معينة. يمكن قول أي شيء.
  • لا يتطلب ثلاث عينات صوتية ولكن يتطلب 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 لإزالة الملف التعريفي.

إضافة التسجيلات إلى ملف التعريف للنص المستقل

حدد الدالة التالية من أجل تسجيل ملف تعريف صوتي:

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 .

Speaker identification

يتم استخدام تعريف المتحدث لتحديد من يتحدث من مجموعة معينة من الأصوات المسجلة. تشبه هذه العملية التحقق المستقل عن النص . يتمثل الاختلاف الرئيسي في القدرة على التحقق من ملفات تعريف صوتية متعددة في وقت واحد بدلاً من التحقق من ملف تعريف واحد.

دالة 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 على النحو التالي:

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

في هذه الدالة، يمكنك إنشاء كائن نموذج تحديد المتحدث SpeakerVerificationModel باستخدام طريقة SpeakerVerificationModel.FromProfile، لتمرير كائن VoiceProfile الذي قمت بإنشائه سابقا.

بعد ذلك، يمكنك استدعاء طريقة SpeechRecognizer.recognizeOnceAsync وتمرير عينة صوت. يحاول SpeechRecognizer.recognizeOnceAsync التعرف على صوت عينة الصوت هذه معتمداً على كائنات VoiceProfile التي استخدمتها لإنشاء SpeakerIdentificationModel . تقوم بإرجاع كائن SpeakerRecognitionResult ، حيث تحدد الخاصية profileId المطابقة VoiceProfile، إن وجدت، بينما تحتوي الخاصية score على درجة تشابه تتراوح بين 0.0 و1.0.

الدالة الرئيسية

أخيرًا، حدد دالة 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

لا يدعم Speech SDK ل Objective-C التعرف على المتحدث. يرجى تحديد لغة برمجة أخرى أو مرجع Objective-C وعينات مرتبطة من بداية هذه المقالة.

وثائق مرجعية | الحزمة (تنزيل) | نماذج إضافية على GitHub

لا يدعم Speech SDK ل Swift التعرف على المتحدث. يرجى تحديد لغة برمجة أخرى أو مرجع Swift والعينات المرتبطة من بداية هذه المقالة.

وثائق مرجعية | Package (PyPi) | عينات إضافية على GitHub

لا يدعم Speech SDK ل Python التعرف على المتحدث. يرجى تحديد لغة برمجة أخرى أو مرجع Python وعينات مرتبطة من بداية هذه المقالة.

مرجع | واجهة برمجة تطبيقات REST لتحويل الكلام إلى نصواجهة برمجة تطبيقات REST لتحويل الكلام إلى نص لمرجع | صوتي قصيرعينات إضافية على GitHub

في هذا التشغيل السريع، تتعلم أنماط التصميم الأساسية للتعرف على المتحدث باستخدام Speech SDK، بما في ذلك:

  • التحقق المعتمد على النص والمستقل عن النص.
  • تحديد المتحدث لتحديد عينة صوتية بين مجموعة من الأصوات.
  • قم بحذف ملفات تعريف الصوت.

لإلقاء نظرة فاحصة على مفاهيم "Speech Recognition"، قم بمراجعة مقالة "overview". راجع العقدة المرجعية في الجزء الأيمن للحصول على قائمة بالأنظمة الأساسية المدعومة.

هام

تحد Microsoft من الوصول إلى التعرف على المتحدث. تطبيق لاستخدامه من خلال نموذج مراجعة الوصول المحدود للتعرف على المتحدث في Azure الذكاء الاصطناعي . بعد الموافقة، يمكنك الوصول إلى واجهات برمجة التطبيقات الخاصة بـSpeaker Recognition.

المتطلبات الأساسية

Text-dependent verification

التحقق من المتحدث هو عملية تأكيد أن المتحدث يطابق صوتًا معروفًا أو مسجل . تتمثل الخطوة الأولى في تسجيل ملف تعريف صوتي بحيث يكون للخدمة شيء ما لمقارنة عينات الصوت المستقبلية به. في هذا المثال، تقوم بتسجيل ملف التعريف باستخدام إستراتيجية تعتمد على النص، والتي تتطلب عبارة مرور معينة لاستخدامها في التسجيل والتحقق. يُرجى الرجوع إلى مستندات المرجع للحصول على قائمة عبارات المرور المعتمدة.

ابدأ بإنشاء ملف تعريف صوتي. ستحتاج إلى إدخال مفتاح الاشتراك في خدمة الكلام والمنطقة في كل من أوامر curl في هذه المقالة.

هام

تذكر إزالة المفتاح من التعليمات البرمجية عند الانتهاء، وعدم نشره على الملأ مطلقًا. للإنتاج، استخدم طريقة آمنة لتخزين بيانات الاعتماد والوصول إليها مثل 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'\''
}'

هناك ثلاثة أنواع من ملفات تعريف الصوت:

  • Text-dependent verification
  • Text-independent verification
  • Text-independent identification

في هذه الحالة، يمكنك إنشاء ملف تعريف صوتي خاص بـtext-dependent verification. يجب أن تتلقى الاستجابة التالية:

{
    "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 Voice Recorder . أو يمكنك إنشاؤه باستخدام نص إلى كلام.

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'

عدم وجـود استجابة.

Text-independent verification

على عكس عملية text-dependent verificationتكون عملية text-independent verification كالآتي:

  • لا يتطلب نطق عبارة مرور معينة. يمكن قول أي شيء.
  • لا يتطلب ثلاث عينات صوتية ولكن يتطلب 20 ثانية من إجمالي الصوت.

ابدأ بإنشاء ملف تعريف text-independent verification.

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'

عدم وجـود استجابة.

Speaker identification

يتم استخدام تعريف المتحدث لتحديد من يتحدث من مجموعة معينة من الأصوات المسجلة. تشبه هذه العملية التحقق المستقل عن النص . يتمثل الاختلاف الرئيسي في القدرة على التحقق من ملفات تعريف صوتية متعددة في وقت واحد بدلاً من التحقق من ملف تعريف واحد.

ابدأ بإنشاء ملف text-independent identification.

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

عدم وجـود استجابة.

يدعم Speech CLI التعرف على المتحدث، لكننا لم نقم بتضمين دليل هنا بعد. يُرجى تحديد لغة برمجة أخرى للبدء والتعرف على المفاهيم.

الخطوات التالية