ऑडियो डिबगिंग

यह आलेख एंड्रॉइड ऑडियो डीबग करने के लिए कुछ युक्तियों और युक्तियों का वर्णन करता है।

टी सिंक

"टी सिंक" एक ऑडियोफ्लिंगर डिबगिंग सुविधा है, जो बाद के विश्लेषण के लिए हाल के ऑडियो के एक छोटे टुकड़े को बनाए रखने के लिए केवल कस्टम बिल्ड में उपलब्ध है। यह वास्तव में जो खेला गया या रिकॉर्ड किया गया था बनाम जो अपेक्षित था, उसके बीच तुलना की अनुमति देता है।

गोपनीयता के लिए टी सिंक संकलन-समय और रन-टाइम दोनों पर डिफ़ॉल्ट रूप से अक्षम है। टी सिंक का उपयोग करने के लिए, आपको इसे पुन: संकलित करके और एक संपत्ति सेट करके इसे सक्षम करने की आवश्यकता होगी। डिबगिंग समाप्त करने के बाद इस सुविधा को अक्षम करना सुनिश्चित करें; उत्पादन निर्माण में टी सिंक को सक्षम नहीं छोड़ा जाना चाहिए।

इस अनुभाग में दिए गए निर्देश Android 7.x और उच्चतर के लिए हैं। Android 5.x और 6.x के लिए, /data/misc/audioserver /data/misc/media से बदलें। इसके अतिरिक्त, आपको userdebug या eng बिल्ड का उपयोग करना होगा। यदि आप यूजरडिबग बिल्ड का उपयोग करते हैं, तो सत्यापन को अक्षम करें:

adb root && adb disable-verity && adb reboot

संकलन-समय सेटअप

  1. cd frameworks/av/services/audioflinger
  2. Configuration.h संपादित करें.h.
  3. टिप्पणी हटाएं #define TEE_SINK
  4. libaudioflinger.so पुनः निर्माण करें।
  5. adb root
  6. adb remount
  7. नए libaudioflinger.so को डिवाइस के /system/lib में पुश या सिंक करें।

रन-टाइम सेटअप

  1. adb shell getprop | grep ro.debuggable
    पुष्टि करें कि आउटपुट है: [ro.debuggable]: [1]
  2. adb shell
  3. ls -ld /data/misc/audioserver

    पुष्टि करें कि आउटपुट है:

    drwx------ media media ... media
    

    यदि निर्देशिका मौजूद नहीं है, तो इसे इस प्रकार बनाएं:

    mkdir /data/misc/audioserver
    chown media:media /data/misc/audioserver
    
  4. echo af.tee=# > /data/local.prop
    जहां af.tee मान नीचे वर्णित एक संख्या है।
  5. chmod 644 /data/local.prop
  6. reboot

af.tee संपत्ति के लिए मूल्य

af.tee का मान 0 और 7 के बीच की एक संख्या है, जो कई बिट्स का योग व्यक्त करता है, प्रति फीचर एक। प्रत्येक बिट के स्पष्टीकरण के लिए AudioFlinger.cpp में AudioFlinger::AudioFlinger() पर कोड देखें, लेकिन संक्षेप में:

  • 1 = इनपुट
  • 2 = फास्टमिक्सर आउटपुट
  • 4 = प्रति-ट्रैक ऑडियोरिकॉर्ड और ऑडियोट्रैक

डीप बफ़र या सामान्य मिक्सर के लिए अभी तक कोई बिट नहीं है, लेकिन आप "4" का उपयोग करके समान परिणाम प्राप्त कर सकते हैं।

परीक्षण करें और डेटा प्राप्त करें

  1. अपना ऑडियो परीक्षण चलाएँ.
  2. adb shell dumpsys media.audio_flinger
  3. dumpsys आउटपुट में इस तरह एक लाइन देखें:
    tee copied to /data/misc/audioserver/20131010101147_2.wav
    यह एक PCM .wav फ़ाइल है.
  4. फिर adb रुचि की कोई भी /data/misc/audioserver/*.wav फ़ाइलें adb pull ; ध्यान दें कि ट्रैक-विशिष्ट डंप फ़ाइल नाम dumpsys आउटपुट में दिखाई नहीं देते हैं, लेकिन ट्रैक बंद होने पर अभी भी /data/misc/audioserver में सहेजे जाते हैं।
  5. दूसरों के साथ साझा करने से पहले गोपनीयता संबंधी चिंताओं के लिए डंप फ़ाइलों की समीक्षा करें।

सुझाव

अधिक उपयोगी परिणामों के लिए इन विचारों को आज़माएँ:

  • परीक्षण आउटपुट में रुकावटों को कम करने के लिए स्पर्श ध्वनियों और कुंजी क्लिक को अक्षम करें।
  • सभी वॉल्यूम अधिकतम करें.
  • यदि वे आपके परीक्षण के लिए रुचिकर नहीं हैं, तो माइक्रोफ़ोन से ध्वनि बनाने या रिकॉर्ड करने वाले ऐप्स को अक्षम कर दें।
  • ट्रैक-विशिष्ट डंप केवल तभी सहेजे जाते हैं जब ट्रैक बंद हो जाता है; आपको किसी ऐप के ट्रैक-विशिष्ट डेटा को डंप करने के लिए उसे बलपूर्वक बंद करने की आवश्यकता हो सकती है
  • परीक्षण के तुरंत बाद dumpsys करें; वहाँ सीमित मात्रा में रिकॉर्डिंग स्थान उपलब्ध है।
  • यह सुनिश्चित करने के लिए कि आप अपनी डंप फ़ाइलें न खोएँ, उन्हें समय-समय पर अपने होस्ट पर अपलोड करें। केवल सीमित संख्या में डंप फ़ाइलें संरक्षित हैं; उस सीमा तक पहुंचने के बाद पुराने डंप हटा दिए जाते हैं।

पुनर्स्थापित करना

जैसा कि ऊपर बताया गया है, टी सिंक सुविधा को सक्षम नहीं छोड़ा जाना चाहिए। अपने बिल्ड और डिवाइस को निम्नानुसार पुनर्स्थापित करें:

  1. स्रोत कोड परिवर्तनों को Configuration.h पर वापस लाएं।
  2. libaudioflinger.so पुनः निर्माण करें।
  3. पुनर्स्थापित libaudioflinger.so को डिवाइस के /system/lib पर पुश या सिंक करें।
  4. adb shell
  5. rm /data/local.prop
  6. rm /data/misc/audioserver/*.wav
  7. reboot

मीडिया.लॉग

ALOGx मैक्रोज़

एंड्रॉइड एसडीके में मानक जावा भाषा लॉगिंग एपीआई android.util.Log है।

एंड्रॉइड एनडीके में संबंधित सी भाषा एपीआई <android/log.h> में घोषित __android_log_print है।

एंड्रॉइड फ्रेमवर्क के मूल भाग के भीतर, हम ALOGE , ALOGW , ALOGI , ALOGV , आदि नामक मैक्रोज़ पसंद करते हैं। उन्हें <utils/Log.h> में घोषित किया गया है, और इस लेख के प्रयोजनों के लिए हम सामूहिक रूप से उन्हें ALOGx के रूप में संदर्भित करेंगे। .

ये सभी एपीआई उपयोग में आसान और अच्छी तरह से समझे जाने वाले हैं, इसलिए ये पूरे एंड्रॉइड प्लेटफ़ॉर्म पर व्यापक हैं। विशेष रूप से mediaserver प्रक्रिया, जिसमें ऑडियोफ्लिंगर ध्वनि सर्वर शामिल है, बड़े पैमाने पर ALOGx का उपयोग करती है।

फिर भी, ALOGx और दोस्तों की कुछ सीमाएँ हैं:

  • वे "लॉग स्पैम" के प्रति संवेदनशील हैं: लॉग बफ़र एक साझा संसाधन है इसलिए यह असंबंधित लॉग प्रविष्टियों के कारण आसानी से ओवरफ़्लो हो सकता है, जिसके परिणामस्वरूप जानकारी छूट जाती है। ALOGV वैरिएंट डिफ़ॉल्ट रूप से संकलन-समय पर अक्षम होता है। लेकिन निश्चित रूप से यदि यह सक्षम है तो इसका परिणाम लॉग स्पैम भी हो सकता है।
  • अंतर्निहित कर्नेल सिस्टम कॉल ब्लॉक हो सकती है, जिसके परिणामस्वरूप संभवतः प्राथमिकता उलट हो सकती है और परिणामस्वरूप माप में गड़बड़ी और अशुद्धियाँ हो सकती हैं। यह FastMixer और FastCapture जैसे समय-महत्वपूर्ण थ्रेड्स के लिए विशेष चिंता का विषय है।
  • यदि लॉग स्पैम को कम करने के लिए किसी विशेष लॉग को अक्षम कर दिया जाता है, तो उस लॉग द्वारा कैप्चर की गई कोई भी जानकारी खो जाती है। यह स्पष्ट हो जाने के बाद कि लॉग दिलचस्प रहा होगा, किसी विशिष्ट लॉग को पूर्वव्यापी रूप से सक्षम करना संभव नहीं है।

एनबीलॉग, मीडिया.लॉग, और मीडियालॉगसर्विस

NBLOG API और संबंधित media.log प्रक्रिया और MediaLogService सेवा मिलकर मीडिया के लिए एक नया लॉगिंग सिस्टम बनाते हैं, और विशेष रूप से उपरोक्त मुद्दों को संबोधित करने के लिए डिज़ाइन किए गए हैं। हम इन तीनों को संदर्भित करने के लिए "मीडिया.लॉग" शब्द का शिथिल रूप से उपयोग करेंगे, लेकिन कड़ाई से कहें तो NBLOG सी++ लॉगिंग एपीआई है, media.log एक लिनक्स प्रक्रिया नाम है, और MediaLogService लॉग की जांच के लिए एक एंड्रॉइड बाइंडर सेवा है।

एक media.log "टाइमलाइन" लॉग प्रविष्टियों की एक श्रृंखला है जिसका सापेक्ष क्रम संरक्षित है। परंपरा के अनुसार, प्रत्येक थ्रेड को अपनी स्वयं की टाइमलाइन का उपयोग करना चाहिए।

फ़ायदे

media.log सिस्टम का लाभ यह है कि:

  • जब तक इसकी आवश्यकता न हो, मुख्य लॉग को स्पैम नहीं करता।
  • mediaserver क्रैश या हैंग होने पर भी जांच की जा सकती है।
  • प्रति टाइमलाइन नॉन-ब्लॉकिंग है।
  • प्रदर्शन में कम व्यवधान प्रदान करता है. (निश्चित रूप से लॉगिंग का कोई भी रूप पूरी तरह से गैर-दखल देने वाला नहीं है।)

वास्तुकला

नीचे दिया गया चित्र media.log प्रस्तुत करने से पहले, mediaserver प्रक्रिया और init प्रक्रिया के संबंध को दर्शाता है:

मीडिया.लॉग से पहले की वास्तुकला

चित्र 1. मीडिया.लॉग से पहले की वास्तुकला

उल्लेखनीय बिंदु:

  • init फोर्क और कार्यकारी mediaserver
  • init mediaserver की मृत्यु का पता लगाता है, और आवश्यकतानुसार पुनः फोर्क करता है।
  • ALOGx लॉगिंग नहीं दिखाई गई है.

नीचे दिया गया चित्र, media.log को आर्किटेक्चर में जोड़े जाने के बाद, घटकों के नए संबंध को दर्शाता है:

Media.log के बाद वास्तुकला

चित्र 2. मीडिया.लॉग के बाद वास्तुकला

महत्वपूर्ण परिवर्तन:

  • ग्राहक लॉग प्रविष्टियाँ बनाने और उन्हें साझा मेमोरी में एक गोलाकार बफर में जोड़ने के लिए NBLOG API का उपयोग करते हैं।
  • MediaLogService किसी भी समय सर्कुलर बफर की सामग्री को डंप कर सकता है।
  • सर्कुलर बफ़र को इस तरह से डिज़ाइन किया गया है कि साझा मेमोरी का कोई भी भ्रष्टाचार MediaLogService क्रैश नहीं करेगा, और यह अभी भी उतने ही बफ़र को डंप करने में सक्षम होगा जो भ्रष्टाचार से प्रभावित नहीं है।
  • नई प्रविष्टियाँ लिखने और मौजूदा प्रविष्टियाँ पढ़ने दोनों के लिए सर्कुलर बफ़र गैर-अवरुद्ध और लॉक-मुक्त है।
  • सर्कुलर बफर (वैकल्पिक टाइमस्टैम्प के अलावा) से लिखने या पढ़ने के लिए किसी कर्नेल सिस्टम कॉल की आवश्यकता नहीं होती है।

कहां उपयोग करें

एंड्रॉइड 4.4 के अनुसार, ऑडियोफ्लिंगर में केवल कुछ लॉग पॉइंट हैं जो media.log सिस्टम का उपयोग करते हैं। हालाँकि नए API का उपयोग करना ALOGx जितना आसान नहीं है, लेकिन वे अत्यधिक कठिन भी नहीं हैं। हम आपको उन अवसरों के लिए नई लॉगिंग प्रणाली सीखने के लिए प्रोत्साहित करते हैं जब यह अपरिहार्य हो। विशेष रूप से, ऑडियोफ़्लिंगर थ्रेड्स के लिए इसकी अनुशंसा की जाती है जिन्हें बार-बार, समय-समय पर और बिना किसी अवरोध के चलना चाहिए जैसे कि 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::Writer के बजाय NBLog::LockedWriter रैपर का उपयोग कर सकते हैं। हालाँकि, यह इस एपीआई के एक प्रमुख लाभ को नकार देता है: इसका गैर-अवरुद्ध व्यवहार।

पूर्ण NBLog API frameworks/av/include/media/nbaio/NBLog.h पर है।

मीडिया.लॉग सक्षम करें

media.log डिफ़ॉल्ट रूप से अक्षम है। यह तभी सक्रिय होता है जब संपत्ति ro.test_harness 1 होती है। आप इसे इसके द्वारा सक्षम कर सकते हैं:

adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot

रिबूट के दौरान कनेक्शन खो जाता है, इसलिए:

adb shell
कमांड ps media अब दो प्रक्रियाएं दिखाएगा:
  • मीडिया.लॉग
  • मीडिया सर्वर

बाद के लिए mediaserver की प्रक्रिया आईडी नोट करें।

समयसीमा प्रदर्शित करें

आप किसी भी समय मैन्युअल रूप से लॉग डंप का अनुरोध कर सकते हैं। यह कमांड सभी सक्रिय और हालिया टाइमलाइन से लॉग दिखाता है, और फिर उन्हें साफ़ करता है:

dumpsys media.log

ध्यान दें कि डिज़ाइन के अनुसार समय-सीमाएँ स्वतंत्र हैं, और समय-सीमाओं के विलय की कोई सुविधा नहीं है।

मीडियासर्वर की मृत्यु के बाद लॉग पुनर्प्राप्त करें

अब mediaserver प्रक्रिया को खत्म करने का प्रयास करें: kill -9 # , जहां # वह प्रक्रिया आईडी है जिसे आपने पहले नोट किया था। आपको मुख्य logcat में media.log से एक डंप देखना चाहिए, जिसमें क्रैश तक पहुंचने वाले सभी लॉग दिखेंगे।

dumpsys media.log