توضّح هذه المقالة بعض النصائح لتصحيح أخطاء الصوت في Android.
حوض استحمام
"حوض الشاي" CANNOT TRANSLATE ميزة تصحيح أخطاء AudioFlinger المتوفّرة في الإصدارات المخصّصة فقط للاحتفاظ بجزء قصير من المحتوى الصوتي الحديث لتحليله لاحقًا. ويسمح ذلك بمقارنة ما تم تشغيله أو تسجيله بالفعل مقارنةً بما كان متوقعًا
للحفاظ على الخصوصية، يتم إيقاف حوض التشغيل بشكل افتراضي، في كل من وقت التجميع وقت التشغيل. لاستخدام حوض قمزة الغولف، ستحتاج إلى تمكينه عن طريق إعادة التجميع وأيضًا من خلال تعيين خاصية. تأكد من إيقاف هذه الميزة بعد تم تصحيح الأخطاء؛ يجب عدم ترك حوض المشاريع مفعّلة في بُنى الإنتاج.
التعليمات الواردة في هذا القسم مخصّصة لنظام التشغيل Android 7.x والإصدارات الأحدث. بالنسبة إلى نظام التشغيل Android:
5.x و6.x، استبدِل /data/misc/audioserver
بـ
/data/misc/media
بالإضافة إلى ذلك، يجب عليك استخدام userdebug أو
بنية المشاركة. في حال استخدام إصدار userdebug، يجب إيقاف التحقق من الصحة باستخدام:
adb root && adb disable-verity && adb reboot
إعداد وقت التجميع
cd frameworks/av/services/audioflinger
- تعديل
Configuration.h
- يُرجى إلغاء التعليق على
#define TEE_SINK
. - إعادة إنشاء
libaudioflinger.so
. adb root
adb remount
- يمكنك تفعيل أو مزامنة "
libaudioflinger.so
" الجديد مع "/system/lib
" في الجهاز.
إعداد وقت التشغيل
adb shell getprop | grep ro.debuggable
التأكّد من أنّ الناتج هو:[ro.debuggable]: [1]
adb shell
ls -ld /data/misc/audioserver
تأكَّد من أنّ الناتج:
drwx------ media media ... media
في حال عدم توفّر الدليل، يمكنك إنشائه على النحو التالي:
mkdir /data/misc/audioserver
chown media:media /data/misc/audioserver
echo af.tee=# > /data/local.prop
عندما تكون قيمةaf.tee
هي رقم على النحو الموضّح أدناه.chmod 644 /data/local.prop
reboot
قيم سمة af.tee
قيمة af.tee
هي رقم بين 0 و7، مع التعبير
مجموع عدة وحدات بت، وحدة لكل خاصية.
الاطّلاع على الرمز الوارد في AudioFlinger::AudioFlinger()
في AudioFlinger.cpp
للحصول على شرح لكل وحدة تحكّم، ولكن بإيجاز:
- 1 = إدخال
- 2 = إخراج FastMixer
- 4 = لكل مسار صوتي أو مقطع صوتي
لا يوجد شيء للمورد الاحتياطي العميق أو الخلاط العادي حتى الآن، ولكن يمكنك الحصول على نتائج مماثلة باستخدام "4".
اختبار البيانات والحصول عليها
- أجرِ اختبار الصوت.
adb shell dumpsys media.audio_flinger
- ابحث عن سطر في الناتج
dumpsys
مثل:
tee copied to /data/misc/audioserver/20131010101147_2.wav
هذا ملف PCM .wav. - ثم
adb pull
أي/data/misc/audioserver/*.wav
ملف يهمّك لاحظ أن أسماء ملفات التفريغ الخاصة بالمقطع الصوتي لا تظهر فيdumpsys
إخراج، ولكن تظل محفوظة في/data/misc/audioserver
عند إغلاق المسار. - يُرجى مراجعة ملف الذاكرة للتحقّق من وجود أي مخاوف تتعلق بالخصوصية قبل مشاركتها مع الآخرين.
الاقتراحات
جرِّب هذه الأفكار للحصول على نتائج أكثر فائدة:
- يمكنك إيقاف أصوات اللمس والنقرات على المفاتيح لتقليل الانقطاعات في إخراج الاختبار.
- رفع مستوى الصوت إلى أقصى حد
- إيقاف التطبيقات التي تصدر صوتًا أو تسجِّل من خلال الميكروفون إذا لم تكن مهتمًا باختبارك.
- يتم حفظ عمليات التفريغ الخاصة بالمقطع الصوتي فقط عند إغلاق المسار. قد تضطر إلى فرض إغلاق التطبيق من أجل تفريغ بياناته الخاصة بالمقطع الصوتي.
- عليك تنفيذ
dumpsys
بعد الاختبار مباشرةً. تتوفّر مساحة محدودة للتسجيل. - للتأكد من عدم فقدان ملفات التفريغ، قم بتحميلها إلى المضيف بشكل دوري. يتم الاحتفاظ بعدد محدود فقط من ملفات التفريغ؛ تتم إزالة بيانات التفريغ القديمة بعد الوصول إلى هذا الحد.
استعادة
كما هو موضح أعلاه، يجب عدم ترك ميزة حوض الماء مفعّلة. يمكنك استعادة الإصدار والجهاز على النحو التالي:
- إعادة تغييرات رمز المصدر إلى
Configuration.h
- إعادة إنشاء
libaudioflinger.so
. - إرسال أو مزامنة
libaudioflinger.so
الذي تمت استعادته إلى/system/lib
بالجهاز. adb shell
rm /data/local.prop
rm /data/misc/audioserver/*.wav
reboot
ملف media.log
وحدات ماكرو ALOGx
واجهة برمجة تطبيقات تسجيل لغة Java القياسية في حزمة تطوير البرامج (SDK) لنظام التشغيل Android android.util.Log.
واجهة برمجة تطبيقات لغة C في Android NDK هي
__android_log_print
المعلَن في <android/log.h>
.
ضمن الجزء الأصلي من إطار عمل Android،
يُفضَّل استخدام وحدات ماكرو "ALOGE
" و"ALOGW
"
ALOGI
وALOGV
وغير ذلك. تم الإعلان عنها في
<utils/Log.h>
، ولأغراض هذه المقالة
سنشير إليها مجتمعة باسم ALOGx
.
جميع واجهات برمجة التطبيقات هذه سهلة الاستخدام وسهلة الفهم، لذا فهي منتشرة
عبر نظام Android الأساسي. وعلى وجه الخصوص mediaserver
التي تشمل خادم الصوت AudioFlinger
ALOGx
على نطاق واسع.
ومع ذلك، هناك بعض القيود المفروضة على ALOGx
والأصدقاء:
-
تكون عرضة لـ "تسجيل الرسائل غير المرغوب فيها": المخزن المؤقت للسجلات هو مورد مشترك
بحيث يمكن أن يتجاوز بسهولة بسبب إدخالات السجل غير ذات الصلة، مما يؤدي إلى
معلومات مفقودة. تم إيقاف الصيغة
ALOGV
في وقت التجميع افتراضيًا. ولكن قد ينتج أيضًا عن ذلك تسجيل محتوى غير مرغوب فيه إذا كان مفعّلاً. -
وقد يتم حظر استدعاءات نظام النواة الأساسية، مما قد ينتج عنه
عكس الأولوية وبالتالي قياس الاضطرابات
وغير الدقيقة. هذا من
بالنسبة إلى سلاسل المحادثات المهمة للوقت، مثل
FastMixer
وFastCapture
، - إذا تم إيقاف سجل معين للحد من السجل غير المرغوب فيه، فسيتم فقدان أي معلومات قد تم الحصول عليها بواسطة هذا السجل. لا يمكن تمكين سجل معين بأثر رجعي، بعد يتضح أنّ السجلّ كان مهمًا.
Nblogger وmedia.log وMediaLogService
واجهات برمجة تطبيقات NBLOG
وmedia.log
المرتبطة
وMediaLogService
تشكل معًا نظام تسجيل أحدث للوسائط،
مصممة لمعالجة المشكلات أعلاه. سنستخدم مصطلح
"media.log" (سجل "media.log" للإشارة إلى هذه السمات الثلاث، ولكن NBLOG
هو
واجهة برمجة تطبيقات تسجيل C++، وmedia.log
هو اسم عملية Linux، وMediaLogService
يعدّ خدمة ربط Android لفحص السجلات.
"المخطط الزمني" لـ media.log
عبارة عن سلسلة
من إدخالات السجل التي يتم الاحتفاظ بترتيبها النسبي.
حسب الاصطلاح، يجب أن تستخدم كل سلسلة محادثات المخطط الزمني الخاص بها.
المزايا
في ما يلي مزايا نظام media.log
:
- لا يتم إرسال رسائل غير مرغوب فيها إلى السجلّ الرئيسي ما لم تكن هناك حاجة إليه.
- يمكن فحصه حتى في حال تعطُّل "
mediaserver
" أو توقُّفه. - لا يؤدي إلى حظر المحتوى وفقًا للمخطط الزمني.
- يؤدي إلى إزعاج أقل بالأداء. (بالطبع لا يعد أي شكل من أشكال التسجيل غير تطفلي على الإطلاق.)
هندسة معمارية
يوضّح الرسم البياني التالي العلاقة بين عملية mediaserver
وعملية init
، قبل طرح media.log
:
النقاط البارزة:
- تتم مشاركة بيانات
init
وexecsmediaserver
. - يرصد
init
وفاةmediaserver
، ويعيد شوكه عند الضرورة. - تسجيل
ALOGx
غير معروض.
يوضح الرسم التخطيطي أدناه العلاقة الجديدة بين المكونات،
بعد إضافة media.log
إلى البنية:
تغييرات مهمة:
-
يستخدم العملاء واجهة برمجة التطبيقات
NBLOG
لإنشاء إدخالات سجلّ وإلحاقها بـ مخزن مؤقت دائري في الذاكرة المشتركة. -
يستطيع
MediaLogService
تفريغ محتوى المخزن المؤقت الدائري في أي وقت. -
تم تصميم المورد الاحتياطي الدائري بطريقة تجعل أي تلف في
لن تتعطّل الذكريات المشترَكة في
MediaLogService
، وسيبقى بالإمكان الوصول إليها. بتفريغ أكبر قدر ممكن من المورد الاحتياطي الذي لا يتأثر بالتلف. - المخزن المؤقت الدائري لا يحجب الصوت ولا يمكن قفله لكل من الكتابة الإدخالات الجديدة وقراءة الإدخالات الحالية.
- لا يلزم وجود استدعاءات نظام نواة للكتابة في المخزن المؤقت الدائري أو القراءة منه (باستثناء الطوابع الزمنية الاختيارية).
أماكن الاستخدام
بدايةً من الإصدار 4.4 من نظام التشغيل Android، لا تتوفّر سوى نقاط تسجيل قليلة في AudioFlinger
التي تستخدم نظام media.log
رغم أن واجهات برمجة التطبيقات الجديدة ليست
وسهلة الاستخدام مثل ALOGx
، ولكنها ليست صعبة للغاية أيضًا.
نحن نشجعك على التعرف على نظام التسجيل الجديد لهؤلاء
المناسبات التي لا يمكن فيها الاستغناء عنها.
ويُنصح على وجه الخصوص باستخدام سلاسل محادثات AudioFlinger التي يجب
بشكل متكرر ودوري وبدون حظر مثل
سلسلة محادثات FastMixer
وFastCapture
.
كيفية الاستخدام
إضافة سجلّات
أولاً، عليك إضافة السجلات إلى الرمز.
في سلسلة المحادثات FastMixer
وFastCapture
، استخدِم رمزًا، مثل:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
بما أنّ المخطط الزمني NBLog
يستخدم فقط FastMixer
و
FastCapture
سلسلة محادثات،
لا داعي للاستبعاد المتبادل.
في سلاسل محادثات AudioFlinger الأخرى، استخدِم السمة mNBLogWriter
:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
بالنسبة إلى سلاسل المحادثات بخلاف FastMixer
وFastCapture
:
يمكن استخدام المخطط الزمني NBLog
لسلسلة المحادثات من خلال كل من سلسلة المحادثات نفسها
من خلال عمليات المربط. لا تقدّم NBLog::Writer
أي
استبعاد متبادل ضمني لكل مخطط زمني، لذا تأكد من حدوث جميع السجلات
ضمن سياق يتم فيه الاحتفاظ بتجاهل سلسلة المحادثات mLock
.
بعد إضافة السجلّات، أعِد إنشاء AudioFlinger.
تنبيه:
يجب توفّر مخطَّط زمني NBLog::Writer
منفصل لكل سلسلة محادثات.
لضمان أمان سلاسل المحادثات، لأنّ المخططات الزمنية تحذف عناصر الاستبعاد المتكرّرة حسب تصميمها إذا كنت
إذا كنت تريد أكثر من سلسلة محادثات واحدة تستخدم المخطط الزمني نفسه، يمكنك حماية حسابك من خلال
كائن المزامنة الحالي (كما هو موضَّح أعلاه في mLock
). أو يمكنك
استخدام برنامج تضمين NBLog::LockedWriter
بدلاً من NBLog::Writer
ومع ذلك، ينفي ذلك إحدى المزايا الرئيسية لواجهة برمجة التطبيقات هذه، ألا وهي:
السلوك.
واجهة برمجة التطبيقات NBLog
الكاملة على frameworks/av/include/media/nbaio/NBLog.h
.
تفعيل ملف media.log
يكون media.log
غير مفعَّل تلقائيًا. تكون نشطة فقط عندما تكون الخاصية
تم 1
ميزة ro.test_harness
. يمكنك تفعيل هذه الميزة من خلال اتّباع الخطوات التالية:
adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot
يتم فقدان الاتصال أثناء إعادة التشغيل، لذا:
adb shell
ps media
الآن عمليتين:
- ملف media.log
- خادم وسائط
سجِّل رقم تعريف العملية "mediaserver
" لوقت لاحق.
عرض المخططات الزمنية
ويمكنك طلب تفريغ السجلّ يدويًا في أي وقت. يعرض هذا الأمر السجلّات من جميع المخططات الزمنية النشطة والحديثة، ثم يمحوها:
dumpsys media.log
لاحظ أنه حسب التصميم تكون الجداول الزمنية مستقلة، ولا توجد إمكانية لدمج الجداول الزمنية.
استرداد السجلات بعد وفاة خادم الوسائط
حاول الآن إنهاء العملية mediaserver
: kill -9 #
، حيث تكون #
بمعرّف العملية الذي لاحظته سابقًا. من المفترض أن يظهر لك ملف تفريغ من media.log
.
في logcat
الرئيسي، مع عرض جميع السجلات التي أدت إلى التعطُّل.
dumpsys media.log