Aऑडियो और MMAP

Aऑडियो एक ऑडियो एपीआई है, जिसे Android 8.0 रिलीज़ में पेश किया गया है. Android 8.1 रिलीज़ को एचएएल के साथ इस्तेमाल करने पर, इंतज़ार का समय कम करने के लिए इसे बेहतर बनाया गया है और ड्राइवर जो MMAP का समर्थन करते हैं. इस दस्तावेज़ में हार्डवेयर ऐब्स्ट्रैक्ट के बारे में बताया गया है Aऑडियो की MMAP सुविधा के सही से काम करने के लिए, लेयर (HAL) और ड्राइवर में बदलाव करने की ज़रूरत है Android.

Aऑडियो MMAP के साथ काम करने के लिए ज़रूरी है कि:

  • एचएएल की एमएमएपी क्षमताओं की रिपोर्टिंग
  • HAL में नए फ़ंक्शन लागू करना
  • EXCLUSIVE मोड बफ़र के लिए वैकल्पिक रूप से कस्टम ioctl() लागू करना
  • हार्डवेयर डेटा का अतिरिक्त पाथ उपलब्ध कराकर
  • ऐसी सिस्टम प्रॉपर्टी सेट करना जो MMAP सुविधा को चालू करती हैं

Aऑडियो आर्किटेक्चर

ऑडियो एक नया नेटिव C API है, जो ओपन SL ES का विकल्प देता है. यह ऑडियो स्ट्रीम बनाने के लिए बिल्डर डिज़ाइन पैटर्न.

A Audio, लो-लेटेंसी डेटा पाथ उपलब्ध कराता है. EXCLUSIVE मोड में, यह सुविधा इससे क्लाइंट ऐप्लिकेशन कोड को, सीधे मेमोरी से मैप किए गए बफ़र में लिखने की अनुमति मिलती है जिसे ALSA ड्राइवर के साथ शेयर किया जाता है. शेयर किए गए मोड में, MMAP बफ़र का इस्तेमाल ऑडियो सर्वर में चल रहा एक मिक्सर है. EXCLUSIVE मोड में, इंतज़ार का समय यह है काफ़ी कम हो जाती है, क्योंकि डेटा मिक्सर को बायपास कर देता है.

EXCLUSIVE मोड में, सेवा HAL से MMAP बफ़र का अनुरोध करती है और संसाधन भी मुहैया कराते हैं. MMAP बफ़र, NOIRQ मोड में चल रहा है, इसलिए इसे शेयर नहीं किया गया है बफ़र का ऐक्सेस मैनेज करने के लिए, पढ़ने/लिखने के लिए काउंटर का इस्तेमाल करें. इसके बजाय, क्लाइंट हार्डवेयर का टाइमिंग मॉडल बनाए रखता है और यह अनुमान लगाता है कि बफ़र कब पढ़ें.

नीचे दिए गए डायग्राम में, पल्स-कोड मॉड्यूलेशन (पीसीएम) का डेटा फ़्लो देखा जा सकता है MMAP FIFO से होते हुए ALSA ड्राइवर में प्रवेश किया जा सकता है. टाइमस्टैंप समय-समय पर Aऑडियो सेवा का अनुरोध किया गया और फिर उसे क्लाइंट के टाइमिंग मॉडल को पास किया गया में से एक को क्रम से लगाया जा सकता है.

पीसीएम डेटा फ़्लो का डायग्राम.
पहली इमेज. FIFO से ALSA में पीसीएम डेटा फ़्लो

शेयर किए गए मोड में, टाइमिंग मॉडल का भी इस्तेमाल किया जाता है, लेकिन यह AAudioService में मौजूद होता है.

ऑडियो कैप्चर के लिए, मिलते-जुलते मॉडल का इस्तेमाल किया जाता है. हालांकि, पीसीएम का डेटा विपरीत दिशा में.

एचएएल में बदलाव

छोटे ALSA के लिए यह देखें:

external/tinyalsa/include/tinyalsa/asoundlib.h
external/tinyalsa/include/tinyalsa/pcm.c
int pcm_start(struct pcm *pcm);
int pcm_stop(struct pcm *pcm);
int pcm_mmap_begin(struct pcm *pcm, void **areas,
           unsigned int *offset,
           unsigned int *frames);
int pcm_get_poll_fd(struct pcm *pcm);
int pcm_mmap_commit(struct pcm *pcm, unsigned int offset,
           unsigned int frames);
int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr,
           struct timespec *tstamp);

लेगसी एचएएल के लिए, यहां देखें:

hardware/libhardware/include/hardware/audio.h
hardware/qcom/audio/hal/audio_hw.c
int start(const struct audio_stream_out* stream);
int stop(const struct audio_stream_out* stream);
int create_mmap_buffer(const struct audio_stream_out *stream,
                        int32_t min_size_frames,
                        struct audio_mmap_buffer_info *info);
int get_mmap_position(const struct audio_stream_out *stream,
                        struct audio_mmap_position *position);

HIDL ऑडियो एचएएल के लिए:

hardware/interfaces/audio/2.0/IStream.hal
hardware/interfaces/audio/2.0/types.hal
hardware/interfaces/audio/2.0/default/Stream.h
start() generates (Result retval);
stop() generates (Result retval) ;
createMmapBuffer(int32_t minSizeFrames)
       generates (Result retval, MmapBufferInfo info);
getMmapPosition()
       generates (Result retval, MmapPosition position);

MMAP सहायता की रिपोर्ट करें

सिस्टम प्रॉपर्टी "aaudio.mmap_policy" 2 (AAUDIO_POLICY_auto) पर सेट होना चाहिए ऑडियो फ़्रेमवर्क को पता है कि MMAP मोड, ऑडियो HAL पर काम करता है. (देखें "Aऑडियो MMAP डेटा पाथ चालू करना" below.)

audio_policy_configuration.xml फ़ाइल में एक आउटपुट और इनपुट भी होना चाहिए MMAP/NO IRQ मोड के लिए विशेष प्रोफ़ाइल, ताकि ऑडियो नीति मैनेजर को पता चल सके MMAP क्लाइंट बनाने के दौरान कौनसी स्ट्रीम खुलेगी:

<mixPort name="mmap_no_irq_out" role="source"
            flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                                samplingRates="48000"
                                channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>

<mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                                samplingRates="48000"
                                channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>

MMAP स्ट्रीम को खोलें और बंद करें

createMmapBuffer(int32_t minSizeFrames)
            generates (Result retval, MmapBufferInfo info);

MMAP स्ट्रीम को Tyalsa फ़ंक्शन को कॉल करके खोला और बंद किया जा सकता है.

क्वेरी MMAP

समय मॉडल पर वापस भेजे गए टाइमस्टैंप में एक फ़्रेम स्थिति और एक नैनोसेकंड में MONOTONIC समय:

getMmapPosition()
        generates (Result retval, MmapPosition position);

HAL एक नए नंबर पर कॉल करके ALSA ड्राइवर से यह जानकारी ले सकता है टाइनीलसा फ़ंक्शन:

int pcm_mmap_get_hw_ptr(struct pcm* pcm,
                        unsigned int *hw_ptr,
                        struct timespec *tstamp);

शेयर की गई मेमोरी के लिए फ़ाइल डिस्क्रिप्टर

Aऑडियो MMAP डेटा पाथ उस मेमोरी क्षेत्र का इस्तेमाल करता है जिसे हार्डवेयर और ऑडियो सेवा. शेयर की गई मेमोरी का रेफ़रंस, फ़ाइल डिस्क्रिप्टर का इस्तेमाल करके दिया गया है जो ALSA ड्राइवर द्वारा जनरेट किया जाता है.

कर्नेल में बदलाव

अगर फ़ाइल डिस्क्रिप्टर किसी /dev/snd/ ड्राइवर फ़ाइल है, तो ऑडियो सेवा इसे इसमें इस्तेमाल कर सकती है शेयर किया गया मोड. हालांकि, डिस्क्रिप्टर को खास मोड. /dev/snd/ फ़ाइल डिस्क्रिप्टर भी यह जानकारी देगा तक पहुंच बढ़ा देती है, इसलिए यह SELinux से अवरोधित है.

EXCLUSIVE मोड पर काम करने के लिए, आपको किसी anon_inode:dmabuf फ़ाइल का /dev/snd/ डिस्क्रिप्टर डिस्क्रिप्टर का इस्तेमाल करें. SELinux फ़ाइल डिस्क्रिप्टर को क्लाइंट को पास करने की अनुमति देता है. यह का इस्तेमाल AAudioService के लिए भी किया जा सकता है.

anon_inode:dmabuf फ़ाइल डिस्क्रिप्टर जनरेट करने के लिए, Android Ion मेमोरी लाइब्रेरी.

ज़्यादा जानकारी के लिए, ये बाहरी संसाधन देखें:

  1. "Android ION मेमोरी ऐलोकेटर" https://lwn.net/articles/480055/
  2. "Android ION के बारे में खास जानकारी" https://wiki.linaro.org/BenjaminGagnard/ion
  3. "आयन मेमोरी ऐलोकेटर को इंटिग्रेट करना" https://lwn.net/articles/565469/

एचएएल में बदलाव

ऑडियो सेवा को यह जानने की ज़रूरत है कि यह anon_inode:dmabuf समर्थित हैं. Android 10.0 से पहले, ऐसा करने का सिर्फ़ एक तरीका था, MMAP के साइज़ को पास करना बफ़र को नेगेटिव नंबर के तौर पर लिखें, जैसे कि -अगर काम करता है, तो 2048 के बजाय 2048. Android 10.0 और उसके बाद के वर्शन में आपके पास AUDIO_MMAP_APPLICATION_SHAREABLE के लिए फ़्लैग सेट करने का विकल्प है.

mmapBufferInfo |= AUDIO_MMAP_APPLICATION_SHAREABLE;

ऑडियो सबसिस्टम में बदलाव

Aऑडियो को ऑडियो के फ़्रंट एंड पर अतिरिक्त डेटा पाथ की ज़रूरत है सब-सिस्टम है, ताकि यह मूल AudioFlinger पाथ के साथ-साथ काम कर सके. इस लेगसी पाथ का इस्तेमाल, अन्य सभी सिस्टम साउंड और ऐप्लिकेशन की साउंड के लिए किया जाता है. यह सुविधा, डीएसपी या हार्डवेयर में मौजूद सॉफ़्टवेयर मिक्सर से मिल सकती है एसओसी में मिक्सर कर सकते हैं.

Aऑडियो MMAP डेटा पाथ चालू करें

अगर MMAP सुविधा काम नहीं करती है, तो Aऑडियो, लेगसी AudioFlinger डेटा पाथ का इस्तेमाल करेगा या स्ट्रीम को खोलने में विफल रहता है. इसलिए, AAudio ऐसे ऑडियो डिवाइस के साथ काम करेगा जो MMAP/NOIRQ पाथ का इस्तेमाल किया जा सकता है.

Aऑडियो के लिए MMAP की सुविधा का टेस्ट करते समय, यह जानना ज़रूरी है कि जो MMAP डेटा पाथ की जांच कर रहे हैं या सिर्फ़ लेगसी डेटा पाथ की जांच कर रहे हैं. कॉन्टेंट बनाने नीचे बताया गया है कि खास डेटा पाथ को कैसे चालू किया जाता है या ज़बरदस्ती कैसे लागू किया जाता है. साथ ही, क्वेरी करने का तरीका भी बताया गया है का इस्तेमाल किया जाता है.

सिस्टम की प्रॉपर्टी

सिस्टम की प्रॉपर्टी की मदद से, MMAP नीति को सेट किया जा सकता है:

  • 1 = AAUDIO_POLICY_NEVER - सिर्फ़ लेगसी पाथ का इस्तेमाल करें. यहाँ तक कि MMAP का उपयोग करने की भी कोशिश न करें.
  • 2 = AAUDIO_POLICY_auto - MMAP का इस्तेमाल करके देखें. अगर यह सुविधा काम नहीं करती या उपलब्ध नहीं है, तो लेगसी पाथ का इस्तेमाल करें.
  • 3 = AAUDIO_POLICY_ALWAYS - सिर्फ़ MMAP पाथ का इस्तेमाल करें. लेगसी प्लैटफ़ॉर्म पर वापस न जाएं पाथ.

इन्हें Makefile डिवाइसों में सेट किया जा सकता है, जैसे कि:

# Enable AAudio MMAP/NOIRQ data path.
# 2 is AAUDIO_POLICY_AUTO so it will try MMAP then fallback to Legacy path.
PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_policy=2
# Allow EXCLUSIVE then fall back to SHARED.
PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_exclusive_policy=2

डिवाइस को चालू करने के बाद, इन वैल्यू को भी बदला जा सकता है. इन बदलावों को लागू करने के लिए, आपको ऑडियो सर्वर को रीस्टार्ट करना होगा. उदाहरण के लिए, MMAP के लिए 'ऑटो' मोड चालू करने के लिए:

adb root
adb shell setprop aaudio.mmap_policy 2
adb shell killall audioserver

इसमें फ़ंक्शन दिए गए हैं ndk/sysroot/usr/include/aaudio/AAudioTesting.h की मदद से, ये काम किए जा सकते हैं MMAP पाथ का इस्तेमाल करने की नीति को बदलें:

aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy);

यह पता लगाने के लिए कि कोई स्ट्रीम, MMAP पाथ का इस्तेमाल कर रही है या नहीं, इसे कॉल करें:

bool AAudioStream_isMMapUsed(AAudioStream* stream);