OpenSL ES لأجهزة Android

توفر هذه الصفحة تفاصيل حول كيفية اختلاف تنفيذ NDK لـ OpenSL ESTM عن المواصفات المرجعية لـ OpenSL ES 1.0.1. عند استخدام رمز نموذجي من المواصفات، قد تحتاج إلى تعديله ليعمل على Android.

وتتوفّر جميع الميزات في الإصدار Android 2.3 (المستوى 9 لواجهة برمجة التطبيقات) والإصدارات الأحدث، ما لم يذكر خلاف ذلك. لا تتوفر بعض الميزات إلا في الإصدار Android 4.0 (المستوى 14 لواجهة برمجة التطبيقات)؛ وقد تم ذكر هذه الميزات.

ملاحظة: يوضّح مستند تعريف التوافق مع Android (CDD) متطلبات الأجهزة والبرامج لجهاز Android متوافق. يمكنك مراجعة التوافق مع Android للحصول على مزيد من المعلومات حول برنامج التوافق بشكل عام، والاطّلاع على CDD للحصول على مستند CDD الفعلي.

يوفّر OpenSL ES واجهة بلغة C يمكن الوصول إليها أيضًا باستخدام لغة C++ ، كما يعرض ميزات مشابهة للأجزاء الصوتية من واجهات برمجة تطبيقات Android Java هذه:

وكما هو الحال مع جميع أدوات Android Native Development Kit (NDK)، فإن الغرض الأساسي من OpenSL ES لنظام التشغيل Android هو تسهيل تنفيذ المكتبات المشتركة ليتم طلبها باستخدام واجهة Java Native Interface (JNI ). ولا يهدف NDK إلى كتابة تطبيقات C/C++ البحتة. إلا أن OpenSL ES هو واجهة برمجة تطبيقات كاملة الميزات، ونتوقع أن تتمكن من تلبية معظم احتياجاتك الصوتية باستخدام واجهة برمجة التطبيقات هذه فقط، بدون الحاجة إلى استدعاء رموز يتم تشغيلها في وقت تشغيل Android.

ملاحظة: استنادًا إلى OpenSL ES، لا تتوافق واجهة برمجة تطبيقات الصوت الأصلي (الصوت العالي الأداء) في Android مع أي ملف شخصي على OpenSL ES 1.0.1 (لعبة أو موسيقى أو هاتف). ويرجع ذلك إلى أنّ Android لا ينفّذ جميع الميزات المطلوبة ضمن أي ملف شخصي. يتم توضيح أي حالات معروفة يتصرف فيها Android بشكل مختلف عن المواصفات في صفحة إضافات Android.

الميزات المكتسبة من المواصفات المرجعية

يكتسب تنفيذ NDK من Android NDK لـ OpenSL ES الكثير من مجموعة الميزات من المواصفات المرجعية، مع بعض القيود.

نقاط الدخول العالمية

يدعم OpenSL ES لنظام التشغيل Android جميع نقاط الدخول العامة في مواصفات Android. تشمل نقاط الدخول هذه ما يلي:

  • slCreateEngine
  • slQueryNumSupportedEngineInterfaces
  • slQuerySupportedEngineInterfaces

الكائنات والواجهات

يعرض الجدول التالي الكائنات والواجهات التي يدعمها تنفيذ NDK في Android لـ OpenSL ES. إذا ظهرت نعم في الخلية، تكون الميزة متاحة في عملية التنفيذ هذه.

يتوافق Android NDK مع العناصر والواجهات.

إبراز مشغِّل الصوت مسجِّل الصوت المحرك تشكيلة النتائج
تحسين الصوت العميق الخفيض نعم لا لا نعم
قائمة انتظار المخزن المؤقت نعم لا لا لا
محدد مواقع بيانات قائمة انتظار المخزن المؤقت نعم: المصدر لا لا لا
الإدارة الديناميكية للواجهة نعم نعم نعم نعم
إرسال التأثير نعم لا لا لا
المحرك لا لا نعم لا
الصدى البيئي لا لا لا نعم
معادِل الصوت نعم لا لا نعم
محدِّد بيانات أجهزة الإدخال والإخراج لا نعم: المصدر لا لا
استخراج البيانات الوصفية نعم: فك الترميز إلى PCM لا لا لا
كتم الصوت بشكل فردي نعم لا لا لا
كائن نعم نعم نعم نعم
أداة تحديد موقع مجموعة النتائج نعم: مصرف لا لا لا
تشغيل نعم لا لا لا
معدّل التشغيل نعم لا لا لا
حالة الجلب المُسبَق نعم لا لا لا
الصدى المُعدّ مسبقًا لا لا لا نعم
تسجيل لا نعم لا لا
استدعاء نعم لا لا لا
محدِّد مواقع بيانات معرّف الموارد المنتظم (URI) نعم: المصدر لا لا لا
أداة المحاكاة الافتراضية نعم لا لا نعم
الصوت نعم لا لا لا

يشرح القسم التالي قيود استخدام بعض هذه الميزات.

القيود

تنطبق بعض القيود على الميزات الواردة في الجدول 1. تمثّل هذه القيود اختلافات عن المواصفات المرجعية. يقدم الجزء المتبقي من هذا القسم معلومات حول هذه الاختلافات.

الإدارة الديناميكية للواجهة

لا يتوافق OpenSL ES لنظام التشغيل Android مع الترميز RemoveInterface أو ResumeInterface.

مجموعات التأثيرات: صدى البيئة والصدى الذي تم إعداده مسبقًا

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

قد يتجاهل النظام الأساسي طلبات التأثير إذا قدرت أن حِمل وحدة المعالجة المركزية سيكون مرتفعًا جدًا.

إرسال التأثير

يتيح SetSendLevel() مستوى إرسال واحد لكل مشغّل صوت.

الصدى البيئي

لا يتوافق الصدى البيئي مع الحقول reflectionsDelay أو reflectionsLevel أو reverbDelay في بنية SLEnvironmentalReverbSettings.

تنسيق بيانات MIME

يمكنك استخدام تنسيق بيانات MIME فقط مع محدد مواقع بيانات معرف الموارد المنتظم (URI) ولمشغل الصوت فقط. ولا يمكنك استخدام تنسيق البيانات هذا مع مسجِّل صوت.

يتطلّب تطبيق OpenSL ES على Android إعداد mimeType على NULL أو سلسلة UTF-8 صالحة. عليك أيضًا إعداد containerType إلى قيمة صالحة. وفي حال عدم الاستناد إلى اعتبارات أخرى، مثل إمكانية النقل إلى تطبيقات أخرى أو تنسيقات محتوى أخرى يتعذّر على التطبيق تحديدها حسب العنوان، ننصحك بضبط السمة mimeType على NULL وcontainerType على SL_CONTAINERTYPE_UNSPECIFIED.

يتوافق OpenSL ES for Android مع تنسيقات الصوت التالية، ما دام نظام Android الأساسي يتيح استخدامها أيضًا:

  • WAV PCM.
  • WAV alaw.
  • WAV ulaw.
  • MP3 Ogg Vorbis.
  • AAC LC.
  • HE-AACv1 (AAC+).
  • HE-AACv2 (AAC+ محسَّن).
  • AMR.
  • FLAC.

ملاحظة: للحصول على قائمة بتنسيقات الصوت المتوافقة مع Android، يُرجى الاطّلاع على تنسيقات الوسائط المتوافقة.

تنطبق القيود التالية على التعامل مع هذه التنسيقات وغيرها في تنفيذ OpenSL ES هذا:

  • يجب أن تكون تنسيقات AAC داخل حاوية MP4 أو ADTS.
  • لا يتوافق OpenSL ES لنظام التشغيل Android مع نظام MIDI.
  • لا تُعد WMA جزءًا من AOSP، ولم نتحقق من توافقها مع OpenSL ES لنظام Android.
  • إن تنفيذ NDK على Android من برنامج OpenSL ES لا يتيح التشغيل المباشر لـ DRM أو المحتوى المشفّر. لتشغيل المحتوى الصوتي المحمي، يجب فك تشفيره في تطبيقك قبل تشغيله، وأن يفرض تطبيقك أي قيود على إدارة الحقوق الرقمية.

لا يتوافق OpenSL ES لنظام التشغيل Android مع الطرق التالية لمعالجة العناصر:

  • Resume()
  • RegisterCallback()
  • AbortAsyncOperation()
  • SetPriority()
  • GetPriority()
  • SetLossOfControlInterfaces()

تنسيق بيانات PCM

PCM هو تنسيق البيانات الوحيد الذي يمكنك استخدامه مع قوائم انتظار المخزن المؤقت. تتمتع تكوينات تشغيل PCM المتوافقة بالخصائص التالية:

  • غير موقّعة 8 بت أو 16 بت.
  • صوت أحادي أو استيريو
  • ترتيب البايت الصغير.
  • الأسعار في العيّنات لما يلي:
    • 8,000 هرتز
    • 11,025 هرتز
    • 12000 هرتز
    • 16000 هرتز
    • 22,050 هرتز
    • 24,000 هرتز
    • 32000 هرتز
    • 44100 هرتز
    • 48000 هرتز

تعتمد الإعدادات التي يتيحها OpenSL ES لنظام Android للتسجيل على الجهاز، وعادةً ما تتوفّر بتردد 16,000 هرتز مونو/16 بت موقَّعة بصرف النظر عن الجهاز المستخدم.

قيمة الحقل samplesPerSec بوحدات المللي هرتز، على الرغم من وجود اسم مضلل. لتجنُّب استخدام القيمة الخاطئة بغير قصد، ننصحك بإعداد هذا الحقل باستخدام أحد الثوابت الرمزية المحددة لهذا الغرض، مثل SL_SAMPLINGRATE_44_1.

يتوافق الإصدار Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات) والإصدارات الأحدث مع بيانات النقطة العائمة.

معدّل التشغيل

يشير معدل التشغيل OpenSL ES إلى السرعة التي يعرض بها الكائن البيانات، معبرًا عنها بآلاف السرعة العادية، أو لكل ميل. على سبيل المثال، معدل التشغيل 1,000 لكل ميل هو 1,000/1,000، أو السرعة العادية. نطاق السعر هو فاصل زمني مغلق يعبّر عن نطاق معدلات التشغيل المحتملة.

وقد يختلف دعم نطاقات معدلات التشغيل والإمكانات الأخرى اعتمادًا على إصدار النظام الأساسي وتنفيذه. يمكن لتطبيقك تحديد هذه الإمكانات في وقت التشغيل عن طريق استخدام PlaybackRate::GetRateRange() أو PlaybackRate::GetCapabilitiesOfRate() لطلب بحث عن الجهاز.

يدعم الجهاز عادةً نطاق المعدل نفسه لمصدر البيانات بتنسيق PCM، ويتراوح معدل الانسجام بين 1000 لكل ميل و1000 لكل ميل للتنسيقات الأخرى، أي أن نطاق معدل الانسجام هو قيمة واحدة فعليًا.

تسجيل

لا يتوافق OpenSL ES لنظام التشغيل Android مع أحداث SL_RECORDEVENT_HEADATLIMIT أو SL_RECORDEVENT_HEADMOVING.

استدعاء

تتيح الطريقة SetLoop() التكرار الحلقي للملف بالكامل. لتفعيل التكرار، اضبط المعلَمة startPos على 0 والمَعلمة endPos على SL_TIME_UNKNOWN.

محدد مواقع بيانات قائمة انتظار المخزن المؤقت

لا يتوافق مشغّل أو مسجّل الصوت المزوّد بمحدِّد موقع بيانات لقائمة انتظار المخزن المؤقت إلا مع تنسيق بيانات PCM.

محدِّد بيانات أجهزة الإدخال والإخراج

لا يتيح OpenSL ES لنظام التشغيل Android استخدام محدِّد مواقع بيانات أجهزة وحدات الإدخال والإخراج إلا عند تحديد محدِّد المواقع كمصدر للبيانات لتطبيق Engine::CreateAudioRecorder(). تهيئة محدِّد بيانات الجهاز باستخدام القيم المتضمّنة في مقتطف الرمز التالي:

SLDataLocator_IODevice loc_dev =
  {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
  SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};

محدِّد مواقع بيانات معرّف الموارد المنتظم (URI)

لا يمكن أن يستخدم OpenSL ES لنظام التشغيل Android إلا محدِّد مواقع بيانات معرّف الموارد المنتظم (URI) مع تنسيق بيانات MIME، ولا يستخدم إلا لمشغِّل الصوت. لا يمكنك استخدام محدد موقع بيانات معرف الموارد المنتظم (URI) لمسجِّل الصوت. لا يمكن لمعرّف الموارد المنتظم (URI) استخدام سوى المخططَين http: وfile:. ولا يُسمح باستخدام مخطّطات أخرى، مثل https: أو ftp: أو content:.

لم نتحقق بعد من توافق rtsp: مع الصوت على نظام Android الأساسي.

هياكل البيانات

يتوافق نظام التشغيل Android مع بُنى بيانات OpenSL ES 1.0.1 التالية:

  • SLDataFormat_MIME
  • SLDataFormat_PCM
  • SLDataLocator_BufferQueue
  • SLDataLocator_IODevice
  • SLDataLocator_OutputMix
  • SLDataLocator_URI
  • SLDataSink
  • SLDataSource
  • SLEngineOption
  • SLEnvironmentalReverbSettings
  • SLInterfaceID

إعدادات النظام الأساسي

تم تصميم OpenSL ES لنظام التشغيل Android للتطبيقات المتعدّدة سلاسل المحادثات وهو آمن من خلال سلاسل التعليمات. وهي تدعم محركًا واحدًا لكل تطبيق وما يصل إلى 32 عنصرًا لكل محرك. وقد تعمل ذاكرة الجهاز ووحدة المعالجة المركزية المتاحة على تقييد عدد الكائنات القابلة للاستخدام.

يتمّ التعرّف على خيارات المحرّك التالية، ولكن يتجاهلها slCreateEngine:

  • SL_ENGINEOPTION_THREADSAFE
  • SL_ENGINEOPTION_LOSSOFCONTROL

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

ملاحظات البرمجة

توفّر ملاحظات برمجة OpenSL ES معلومات تكميلية لضمان التنفيذ الصحيح لواجهة OpenSL ES.

ملاحظة: للتيسير عليك، أدرجنا نسخة من مواصفات OpenSL ES 1.0.1 مع NDK في docs/opensles/OpenSL_ES_Specification_1.0.1.pdf.

مشاكل النظام الأساسي

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

الإدارة الديناميكية للواجهة

لا يعمل DynamicInterfaceManagement::AddInterface. بدلاً من ذلك، حدِّد الواجهة في الصفيف الذي يتم تمريره إلى Create()، كما هو موضّح في رمز المثال الخاص بالصدى البيئي.

التخطيط للإصدارات المستقبلية من OpenSL ES

تستند واجهات برمجة تطبيقات الصوت العالية الأداء في Android إلى Khronos Group OpenSL ES 1.0.1. أطلقت كرونوس الإصدار 1.1 المنقّح من المعيار. تتضمن النسخة المنقحة ميزات جديدة وتوضيحات وتصحيحات للأخطاء المطبعية وبعض حالات عدم التوافق. معظم حالات عدم التوافق المتوقعة بسيطة نسبيًا أو في مناطق من OpenSL ES التي لا تتوافق مع Android.

من المفترض أن يعمل التطبيق الذي تم تطويره باستخدام هذا الإصدار على الإصدارات المستقبلية من نظام Android الأساسي، بشرط اتّباع الإرشادات الموضحة في قسم التخطيط للتوافق الثنائي أدناه.

ملاحظة: إنّ توافق المصادر المستقبلية ليس هدفًا. ويعني هذا أنه إذا تمت الترقية إلى إصدار أحدث من NDK، فقد تحتاج إلى تعديل رمز مصدر التطبيق ليتوافق مع واجهة برمجة التطبيقات الجديدة. نتوقع أن تكون معظم هذه التغييرات طفيفة، انظر التفاصيل أدناه.

التخطيط للتوافق الثنائي

ننصح بأن يتّبع تطبيقك هذه الإرشادات لتحسين التوافق الثنائي في المستقبل:

  • استخدِم فقط المجموعة الفرعية الموثَّقة من الميزات المتوافقة مع Android من OpenSL ES 1.0.1.
  • ولا تعتمد على رمز نتيجة معيّن لإجراء عملية غير ناجحة، وكُن مستعدًا للتعامل مع رمز نتيجة مختلف.
  • تعمل معالِجات استدعاء التطبيقات بشكلٍ عام في سياق مقيَّد. يجب كتابتها لأداء العمل بسرعة، ثم العودة في أقرب وقت ممكن. لا تشغِّل عمليات معقدة ضمن معالج استدعاء. على سبيل المثال، ضمن معاودة الاتصال بإكمال قائمة انتظار المخزن المؤقت، يمكنك إضافة مورد احتياطي آخر إلى قائمة الانتظار، بدون إنشاء مشغّل صوت.
  • يجب تجهيز معالِجات معاودة الاتصال ليتم طلبها مرات أكثر أو أقل تكرارًا لتلقّي أنواع أحداث إضافية، ويجب أن تتجاهل أنواع الأحداث التي لا تتعرّف عليها. يجب إعداد عمليات معاودة الاتصال التي تم ضبطها باستخدام قناع حدث مصنوع من أنواع أحداث مفعّلة ليتم طلبها مع ضبط وحدات بت متعددة للأحداث في الوقت نفسه. استخدِم "&" لاختبار كل بت خاص بالحدث بدلاً من حالة تبديل.
  • استخدِم حالة الجلب المُسبَق واستدعاءات الاتصال كمؤشرات عامة لمدى التقدّم، ولكن لا تعتمد على مستويات تعبئة محدّدة غير قابلة للتغيير في البرنامج أو تسلسلات معاودة الاتصال. قد يتغيّر معنى مستوى تعبئة حالة الجلب المُسبَق وسلوك الأخطاء التي يتم رصدها أثناء الجلب المُسبَق.

ملاحظة: يمكنك الاطّلاع على قسم سلوك قائمة الانتظار المؤقت أدناه للاطّلاع على مزيد من التفاصيل.

التخطيط لتوافق المصادر

وكما أسلفنا، يُتوقع عدم توافق رمز المصدر في الإصدار التالي من OpenSL ES من Khronos Group. تشمل مجالات التغيير المحتملة ما يلي:

  • من المتوقّع أن تطرأ تغييرات مهمة على واجهة قائمة انتظار المخزن المؤقت، خاصةً في أجزاء BufferQueue::Enqueue، وقائمة المَعلمات لـ slBufferQueueCallback واسم الحقل SLBufferQueueState.playIndex. نقترح عليك أن يستخدم رمز التطبيق قوائم انتظار مخزن بيانات Android الاحتياطي البسيط بدلاً من ذلك. وفي مثال الرمز البرمجي المقدَّم مع NDK، استخدمنا قوائم انتظار المخزن المؤقت البسيط لنظام التشغيل Android للتشغيل لهذا السبب. (نستخدم أيضًا قائمة انتظار المخزن المؤقت البسيط لنظام التشغيل Android للتسجيل وفك الترميز إلى PCM، ولكن ذلك لأن المعيار OpenSL ES 1.0.1 لا يتيح التسجيل أو فك الترميز إلى مصدر بيانات قائمة انتظار المخزن المؤقت).
  • ستتم إضافة const إلى معلَمات الإدخال التي تم تمريرها من خلال المرجع، وستتم إضافة SLchar * إلى حقول البنية المستخدَمة كقيم إدخال. من المفترض ألا يتطلّب ذلك إجراء أي تغييرات على الرمز.
  • سيتم استبدال الأنواع غير الموقعة ببعض المَعلمات الموقَّعة حاليًا. قد تحتاج إلى تغيير نوع المَعلمة من SLint32 إلى SLuint32 أو ما شابه، أو إضافة بث.
  • تنسخ Equalizer::GetPresetName السلسلة إلى ذاكرة التطبيق بدلاً من عرض المؤشر لذاكرة التنفيذ. سيكون هذا تغييرًا كبيرًا، لذا ننصحك بتجنّب استدعاء هذه الطريقة أو عزل استخدامها.
  • ستكون هناك حقول إضافية في أنواع البنية. بالنسبة إلى معلَمات الإخراج، يمكن تجاهل هذه الحقول الجديدة، ولكن يجب إعداد الحقول الجديدة بالنسبة إلى معلَمات الإدخال. ومن المتوقّع أن تكون كل هذه المجالات في المناطق التي لا تعمل بها Android.
  • ستتغير الواجهة GUIDs. يمكنك الرجوع إلى الواجهات حسب اسم رمزي بدلاً من المعرّف الفريد العمومي (GUID) لتجنُّب التبعية.
  • سيتم تغيير قيمة SLchar من unsigned char إلى char. ويؤثر هذا بشكل أساسي في محدِّد مواقع بيانات معرّف الموارد المنتظم (URI) وتنسيق بيانات MIME.
  • ستتم إعادة تسمية SLDataFormat_MIME.mimeType إلى pMimeType، وستتم إعادة تسمية SLDataLocator_URI.URI إلى pURI. وننصحك بإعداد بنيتَي بيانات SLDataFormat_MIME وSLDataLocator_URI باستخدام قائمة قيم مفصولة بفواصل ومحاطة بأقواس بدلاً من اسم الحقل لعزل الرمز عن هذا التغيير. ويُستخدم هذا الأسلوب في نموذج الرمز البرمجي.
  • لا تسمح السمة SL_DATAFORMAT_PCM للتطبيق بتحديد تمثيل البيانات كعدد صحيح بعلامة أو عدد صحيح غير موقَّع أو نقطة عائمة. وتفترض آلية تنفيذ نظام التشغيل Android أنّ بيانات 8 بت هي عبارة عن عدد صحيح غير مُوقَّع، وأنّ 16 بت هي عدد صحيح موقَّع. بالإضافة إلى ذلك، يُعدّ الحقل samplesPerSec اسمًا خاطئًا، لأنّ الوحدات الفعلية هي بالمللي هرتز. ومن المتوقّع أن تتم معالجة هذه المشاكل في إصدار OpenSL ES التالي الذي سيوفّر تنسيقًا جديدًا لبيانات PCM موسّعًا يسمح للتطبيق بتحديد التمثيل بوضوح وتصحيح اسم الحقل. بما أنّ تنسيق البيانات هذا سيكون جديدًا، وسيظل التنسيق الحالي لبيانات PCM متاحًا (ولكنه متوقف)، من المفترض ألا يتطلّب إجراء أي تغييرات فورية على الرمز الخاص بك.