ऑडियो से जुड़ी नीतियां कॉन्फ़िगर करना

Android 10 रिलीज़ में, ऑडियो नीति मैनेजर को फिर से तैयार किया गया है. इससे, वाहन से जुड़े कॉम्प्लेक्स इस्तेमाल के उदाहरणों के लिए ज़्यादा सुविधाएं मिलती हैं:

  • OEM के हिसाब से रूटिंग की रणनीतियां.
  • एक ही वॉल्यूम कर्व का इस्तेमाल करने वाली लेगसी स्ट्रीम टाइप के ग्रुप के लिए, वॉल्यूम के कस्टमाइज़ किए जा सकने वाले ग्रुप.
  • हार्ड कोड होने के बजाय, ऑडियो नीति इंजन की ओर से बताई गई रूटिंग की रणनीतियां.
  • ऑडियो नीति इंजन की मदद से मैनेज किए जाने वाले वॉल्यूम कर्व और ग्रुप.
  • आम कोड और कॉन्फ़िगर किए जा सकने वाले कोड के बीच, आने वाले समय में होने वाले बंटवारे की तैयारी के लिए, इंटरनल रीफ़ैक्टरिंग की जा रही है. साथ ही, ऑडियो डिवाइस को बेहतर तरीके से मैनेज करने की सुविधा भी दी जा रही है. उदाहरण के लिए, नीति के नियमों में डिवाइस प्रॉपर्टी के सभी टाइप का इस्तेमाल करना, न कि सिर्फ़ उसका टाइप.

Android 7.0 में, ऑडियो नीति कॉन्फ़िगरेशन फ़ाइल फ़ॉर्मैट (एक्सएमएल) को शामिल किया गया है. इससे, ऑडियो टोपोलॉजी के बारे में जानकारी मिलती है.

Android के पिछले वर्शन में, अपने प्रॉडक्ट पर मौजूद ऑडियो डिवाइसों की जानकारी देने के लिए, device/<company>/<device>/audio/audio_policy.conf का इस्तेमाल करना ज़रूरी था. device/samsung/tuna/audio/audio_policy.conf में, Galaxy Nexus के ऑडियो हार्डवेयर के लिए इस फ़ाइल का उदाहरण देखा जा सकता है. हालांकि, CONF एक आसान और मालिकाना फ़ॉर्मैट है. यह टेलिविज़न और वाहनों जैसे वर्टिकल के लिए, जटिल टोपोलॉजी के बारे में बताने के लिए बहुत सीमित है.

Android 7.0 में audio_policy.conf को बंद कर दिया गया है. साथ ही, एक्सएमएल फ़ाइल फ़ॉर्मैट का इस्तेमाल करके ऑडियो टोपोलॉजी तय करने की सुविधा जोड़ी गई है. यह फ़ॉर्मैट, मनुष्य के लिए ज़्यादा पढ़ने लायक है. इसमें बदलाव करने और पार्स करने के कई टूल मौजूद हैं. साथ ही, यह जटिल ऑडियो टोपोलॉजी के बारे में बताने के लिए काफ़ी सुविधाजनक है. Android 7.0, कॉन्फ़िगरेशन फ़ाइलों के एक्सएमएल फ़ॉर्मैट को चुनने के लिए, USE_XML_AUDIO_POLICY_CONF बिल्ड फ़्लैग का इस्तेमाल करता है.

एक्सएमएल फ़ॉर्मैट के फ़ायदे

CONF फ़ाइल की तरह, एक्सएमएल फ़ाइल में भी आउटपुट और इनपुट स्ट्रीम प्रोफ़ाइलों की संख्या और टाइप, प्लेबैक और कैप्चर के लिए इस्तेमाल किए जा सकने वाले डिवाइसों, और ऑडियो एट्रिब्यूट तय किए जा सकते हैं. इसके अलावा, एक्सएमएल फ़ॉर्मैट में ये बेहतर सुविधाएं मिलती हैं:

  • Android 10 में, एक से ज़्यादा ऐप्लिकेशन से एक साथ रिकॉर्डिंग की जा सकती है.
    • एक साथ कई गतिविधियां होने की वजह से, रिकॉर्डिंग शुरू करने का अनुरोध कभी अस्वीकार नहीं किया जाता.
    • registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb) कॉलबैक, क्लाइंट को कैप्चर पाथ में हुए बदलावों की सूचना देता है.
  • इन स्थितियों में, क्लाइंट को साइलेंट ऑडियो सैंपल मिलते हैं:
    • निजता से जुड़ा कोई इस्तेमाल का उदाहरण (उदाहरण के लिए, VOICE_COMMUNICATION) चालू है.
    • क्लाइंट में फ़ोरग्राउंड सेवा या फ़ोरग्राउंड यूज़र इंटरफ़ेस (यूआई) नहीं है.
    • नीति में खास भूमिकाओं के लिए ये शर्तें तय की गई हैं:
      • सुलभता सेवा: निजता से जुड़े संवेदनशील इस्तेमाल के उदाहरण के चालू होने पर भी रिकॉर्ड कर सकती है.
      • Assistant: अगर यूज़र इंटरफ़ेस (यूआई) सबसे ऊपर है, तो इसे निजता के लिहाज़ से संवेदनशील माना जाता है.
  • ऑडियो प्रोफ़ाइल का स्ट्रक्चर, एचडीएमआई के सिंपल ऑडियो डिस्क्रिप्टर जैसा ही होता है. इससे हर ऑडियो फ़ॉर्मैट के लिए, सैंपलिंग रेट/चैनल मास्क का अलग सेट चालू किया जा सकता है.
  • डिवाइसों और स्ट्रीम के बीच सभी संभावित कनेक्शन के लिए, साफ़ तौर पर परिभाषाएं दी गई हैं. पहले, एक ही एचएएल मॉड्यूल से जुड़े सभी डिवाइसों को कनेक्ट करने की सुविधा, एक खास नियम के तहत मिलती थी. इसकी वजह से, ऑडियो नीति, ऑडियो पैच एपीआई के ज़रिए किए गए कनेक्शन को कंट्रोल नहीं कर पाती थी. एक्सएमएल फ़ॉर्मैट में, टोपोलॉजी की जानकारी से कनेक्शन की सीमाओं के बारे में पता चलता है.
  • includes के लिए सहायता, स्टैंडर्ड A2DP, USB या सबमिट करने की परिभाषाओं को फिर से भेजने से बचाती है.
  • वॉल्यूम कर्व को पसंद के मुताबिक बनाया जा सकता है. पहले, वॉल्यूम टेबल को हार्डकोड किया जाता था. एक्सएमएल फ़ॉर्मैट में, वॉल्यूम टेबल के बारे में बताया गया है और इन्हें पसंद के मुताबिक बनाया जा सकता है.

frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml पर मौजूद टेंप्लेट में, इनमें से कई सुविधाओं का इस्तेमाल किया गया है.

फ़ाइल फ़ॉर्मैट और जगह

ऑडियो नीति की नई कॉन्फ़िगरेशन फ़ाइल, audio_policy_configuration.xml है और यह /system/etc में मौजूद है. यहां दिए गए उदाहरणों में, Android 12 और इससे पहले के वर्शन के लिए, ऑडियो नीति का एक आसान कॉन्फ़िगरेशन दिखाया गया है. यह कॉन्फ़िगरेशन, एक्सएमएल फ़ाइल फ़ॉर्मैट में है.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <globalConfiguration speaker_drc_enabled="true"/>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>Speaker</item>
                <item>Earpiece</item>
                <item>Built-In Mic</item>
            </attachedDevices>
            <defaultOutputDevice>Speaker</defaultOutputDevice>
            <mixPorts>
                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="primary input" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000 16000 48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000 16000 48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000 16000 48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="Earpiece" sources="primary output"/>
                <route type="mix" sink="Speaker" sources="primary output"/>
                <route type="mix" sink="Wired Headset" sources="primary output"/>
                <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/>
            </routes>
        </module>
        <xi:include href="a2dp_audio_policy_configuration.xml"/>
    </modules>

    <xi:include href="audio_policy_volumes.xml"/>
    <xi:include href="default_volume_tables.xml"/>
</audioPolicyConfiguration>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <globalConfiguration speaker_drc_enabled="true"/>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>Speaker</item>
                <item>Earpiece</item>
                <item>Built-In Mic</item>
            </attachedDevices>
            <defaultOutputDevice>Speaker</defaultOutputDevice>
            <mixPorts>
                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="primary input" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
                   <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
                <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="8000,16000,48000"
                             channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="Earpiece" sources="primary output"/>
                <route type="mix" sink="Speaker" sources="primary output"/>
                <route type="mix" sink="Wired Headset" sources="primary output"/>
                <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/>
            </routes>
        </module>
        <xi:include href="a2dp_audio_policy_configuration.xml"/>
    </modules>

    <xi:include href="audio_policy_volumes.xml"/>
    <xi:include href="default_volume_tables.xml"/>
</audioPolicyConfiguration>

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

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

वॉल्यूम टेबल, पॉइंट की ऐसी आसान सूचियां होती हैं जिनसे यूज़र इंटरफ़ेस (यूआई) इंडेक्स को डीबी में वॉल्यूम में बदलने के लिए इस्तेमाल किए जाने वाले कर्व की जानकारी मिलती है. एक अलग शामिल की गई फ़ाइल, डिफ़ॉल्ट कर्व उपलब्ध कराती है. हालांकि, किसी इस्तेमाल के उदाहरण और डिवाइस कैटगरी के लिए हर कर्व को बदला जा सकता है.

<?xml version="1.0" encoding="UTF-8"?>
<volumes>
    <reference name="FULL_SCALE_VOLUME_CURVE">
        <point>0,0</point>
        <point>100,0</point>
    </reference>
    <reference name="SILENT_VOLUME_CURVE">
        <point>0,-9600</point>
        <point>100,-9600</point>
    </reference>
    <reference name="DEFAULT_VOLUME_CURVE">
        <point>1,-4950</point>
        <point>33,-3350</point>
        <point>66,-1700</point>
        <point>100,0</point>
    </reference>
</volumes>
<?xml version="1.0" encoding="UTF-8"?>
<volumes>
    <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
        <point>1,-5500</point>
        <point>20,-4300</point>
        <point>86,-1200</point>
        <point>100,0</point>
    </volume>
    <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>

    <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
    <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
</volumes>

फ़ाइल में शामिल की गई चीज़ें

एक्सएमएल शामिल करने (XInclude) के तरीके का इस्तेमाल करके, अन्य एक्सएमएल फ़ाइलों में मौजूद ऑडियो नीति के कॉन्फ़िगरेशन की जानकारी शामिल की जा सकती है. शामिल की गई सभी फ़ाइलों का स्ट्रक्चर, ऊपर बताए गए स्ट्रक्चर के मुताबिक होना चाहिए. साथ ही, इनमें ये पाबंदियां भी लागू होनी चाहिए:

  • फ़ाइलों में सिर्फ़ टॉप-लेवल एलिमेंट हो सकते हैं.
  • फ़ाइलों में XInclude एलिमेंट नहीं हो सकते.

स्टैंडर्ड Android Open Source Project (AOSP) के ऑडियो एचएएल मॉड्यूल कॉन्फ़िगरेशन की जानकारी को, ऑडियो नीति की सभी कॉन्फ़िगरेशन फ़ाइलों में कॉपी करने से बचने के लिए, 'शामिल करें' का इस्तेमाल किया जाता है. ऐसा करने पर, गड़बड़ियां होने की संभावना कम हो जाती है. यहां दिए गए ऑडियो एचएएल के लिए, ऑडियो नीति कॉन्फ़िगरेशन की स्टैंडर्ड एक्सएमएल फ़ाइल दी गई है:

  • A2DP: a2dp_audio_policy_configuration.xml
  • सबमिक्स को फिर से रूट करना: rsubmix_audio_policy_configuration.xml
  • यूएसबी: usb_audio_policy_configuration.xml

ऑडियो नीति कोड का संगठन

AudioPolicyManager.cpp को कई मॉड्यूल में बांटा गया है, ताकि इसे मैनेज और कॉन्फ़िगर करना आसान हो. frameworks/av/services/audiopolicy के संगठन में ये मॉड्यूल शामिल हैं.

मॉड्यूल ब्यौरा
/managerdefault इसमें सभी ऐप्लिकेशन के लिए सामान्य इंटरफ़ेस और व्यवहार लागू करने की सुविधा शामिल होती है. AudioPolicyManager.cpp की तरह ही, इसमें इंजन की सुविधाएं और सामान्य कॉन्सेप्ट शामिल नहीं हैं.
/common बुनियादी क्लास तय करता है. उदाहरण के लिए, इनपुट आउटपुट ऑडियो स्ट्रीम प्रोफ़ाइलों, ऑडियो डिवाइस डिस्क्रिप्टर, ऑडियो पैच, और ऑडियो पोर्ट के लिए डेटा स्ट्रक्चर. इसे पहले AudioPolicyManager.cpp में तय किया गया था.
/engine

ऐसे नियम लागू करता है जिनसे यह तय होता है कि किसी खास इस्तेमाल के उदाहरण के लिए, किस डिवाइस और वॉल्यूम का इस्तेमाल किया जाना चाहिए. यह सामान्य हिस्से के साथ एक स्टैंडर्ड इंटरफ़ेस लागू करता है. जैसे, किसी दिए गए वीडियो चलाने या कैप्चर करने के उदाहरण के लिए सही डिवाइस पाने के लिए या कनेक्ट किए गए डिवाइसों या बाहरी स्थिति (यानी, जब कॉल के लिए किसी डिवाइस का इस्तेमाल ज़रूरी हो) को सेट करने के लिए, जो रूटिंग के फ़ैसले में बदलाव कर सकता है.

यह दो वर्शन में उपलब्ध है: कॉन्फ़िगर किया जा सकने वाला और डिफ़ॉल्ट. वर्शन चुनने का तरीका जानने के लिए, पैरामीटर फ़्रेमवर्क का इस्तेमाल करके कॉन्फ़िगरेशन लेख पढ़ें.

/engineconfigurable पैरामीटर फ़्रेमवर्क पर आधारित नीति इंजन लागू करना (नीचे देखें). कॉन्फ़िगरेशन, पैरामीटर फ़्रेमवर्क पर आधारित होता है. साथ ही, यह उस जगह पर भी होता है जहां नीति को एक्सएमएल फ़ाइलों से तय किया जाता है.
/enginedefault Android Audio Policy Manager के पिछले वर्शन के आधार पर, नीति इंजन लागू करना. यह डिफ़ॉल्ट तौर पर लागू होता है. इसमें हार्ड कोड किए गए ऐसे नियम शामिल होते हैं जो Nexus और AOSP के लागू होने से जुड़े होते हैं.
/service इसमें बाकी फ़्रेमवर्क के इंटरफ़ेस के साथ बाइंडर इंटरफ़ेस, थ्रेडिंग, और लॉकिंग लागू करने की सुविधा शामिल है.

पैरामीटर फ़्रेमवर्क का इस्तेमाल करके कॉन्फ़िगरेशन

ऑडियो नीति कोड को इस तरह से व्यवस्थित किया गया है कि उसे समझना और मैनेज करना आसान हो. साथ ही, यह पूरी तरह से कॉन्फ़िगरेशन फ़ाइलों से तय की गई ऑडियो नीति के साथ काम करता है. संगठन और ऑडियो नीति का डिज़ाइन, Intel के पैरामीटर फ़्रेमवर्क पर आधारित है. यह पैरामीटर को मैनेज करने के लिए, प्लग इन और नियम पर आधारित फ़्रेमवर्क है.

कॉन्फ़िगर की जा सकने वाली ऑडियो नीति का इस्तेमाल करके, वेंडर OEM ये काम कर सकते हैं:

  • एक्सएमएल में किसी सिस्टम के स्ट्रक्चर और उसके पैरामीटर के बारे में बताएं.
  • बताए गए पैरामीटर को ऐक्सेस करने के लिए, C++ में लिखें या बैकएंड (प्लग इन) का फिर से इस्तेमाल करें.
  • एक्सएमएल या डोमेन के हिसाब से बनी भाषा में, ऐसी शर्तें/नियम तय करें जिनके आधार पर किसी पैरामीटर को कोई वैल्यू लेनी चाहिए.

AOSP में, ऑडियो नीति की कॉन्फ़िगरेशन फ़ाइल का एक उदाहरण शामिल है. यह फ़ाइल Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml पर पैरामीटर फ़्रेमवर्क का इस्तेमाल करती है. ज़्यादा जानकारी के लिए, पैरामीटर फ़्रेमवर्क के बारे में Intel का दस्तावेज़ देखें.

Android 10 या इससे पहले के वर्शन में, कॉन्फ़िगर की जा सकने वाली ऑडियो नीति को चुनने के लिए, बिल्ड विकल्प USE_CONFIGURABLE_AUDIO_POLICY का इस्तेमाल किया जाता है. Android 11 या उसके बाद के वर्शन में, ऑडियो नीति के इंजन का वर्शन audio_policy_configuration.xml फ़ाइल में चुना जाता है. कॉन्फ़िगर किए जा सकने वाले ऑडियो नीति इंजन को चुनने के लिए, globalConfiguration एलिमेंट के engine_library एट्रिब्यूट की वैल्यू को configurable पर सेट करें. उदाहरण के लिए:

<audioPolicyConfiguration>
    <globalConfiguration engine_library="configurable" />
...
</audioPolicyConfiguration>

ऑडियो नीति रूटिंग एपीआई

Android 6.0 में, सार्वजनिक एलिमेंट और सिलेक्शन एपीआई को शामिल किया गया है. यह एपीआई, ऑडियो पैच/ऑडियो पोर्ट इन्फ़्रास्ट्रक्चर के ऊपर काम करता है. साथ ही, ऐप्लिकेशन डेवलपर को कनेक्ट किए गए ऑडियो रिकॉर्ड या ट्रैक के लिए, किसी डिवाइस के आउटपुट या इनपुट की प्राथमिकता तय करने की सुविधा देता है.

Android 7.0 में, Enumeration और Selection API की पुष्टि सीटीएस टेस्ट से की जाती है. साथ ही, इसे नेटिव C/C++ (OpenSL ES) ऑडियो स्ट्रीम के लिए रूटिंग को शामिल करने के लिए एक्सटेंड किया गया है. नेटिव स्ट्रीम को Java में ही रूट किया जाता है. इसमें AudioRouting इंटरफ़ेस जोड़ा गया है, जो AudioTrack और AudioRecord क्लास के लिए खास तौर पर बनाए गए, साफ़ तौर पर रूटिंग करने के तरीकों को बदल देता है, उनका इस्तेमाल बंद कर देता है, और उनका इस्तेमाल एक साथ करता है.

एलिमेंट और सिलेक्शन एपीआई के बारे में ज़्यादा जानने के लिए, Android कॉन्फ़िगरेशन इंटरफ़ेस और OpenSLES_AndroidConfiguration.h देखें. ऑडियो रूटिंग के बारे में ज़्यादा जानने के लिए, AudioRouting देखें.

एक से ज़्यादा चैनलों पर सहायता

अगर आपका हार्डवेयर और ड्राइवर, एचडीएमआई के ज़रिए मल्टीचैनल ऑडियो के साथ काम करता है, तो ऑडियो स्ट्रीम को सीधे ऑडियो हार्डवेयर पर आउटपुट किया जा सकता है. इससे, ऑडियो फ़्लिंजर मिक्सर को बायपास किया जाता है, ताकि इसे दो चैनलों में डाउनमिक्स न किया जाए. ऑडियो एचएएल को यह बताना होगा कि किसी आउटपुट स्ट्रीम प्रोफ़ाइल में मल्टीचैनल ऑडियो की सुविधाएं काम करती हैं या नहीं. अगर एचएएल अपनी क्षमताओं को दिखाता है, तो डिफ़ॉल्ट नीति मैनेजर, एचडीएमआई पर मल्टीचैनल वीडियो चलाने की अनुमति देता है. लागू करने से जुड़ी जानकारी के लिए, device/samsung/tuna/audio/audio_hw.c देखें.

यह बताने के लिए कि आपके प्रॉडक्ट में मल्टीचैनल ऑडियो आउटपुट है, ऑडियो नीति की कॉन्फ़िगरेशन फ़ाइल में बदलाव करें. इससे, आपके प्रॉडक्ट के मल्टीचैनल आउटपुट के बारे में जानकारी मिलती है. frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml के इस उदाहरण में, डाइनैमिक चैनल मास्क दिखाया गया है. इसका मतलब है कि ऑडियो नीति मैनेजर, कनेक्ट होने के बाद एचडीएमआई सिंक के साथ काम करने वाले चैनल मास्क के बारे में क्वेरी करता है.

<module name="primary" halVersion="2.0">
    <attachedDevices>
        <item>Speaker</item>
    </attachedDevices>
    <defaultOutputDevice>Speaker</defaultOutputDevice>
    <mixPorts>
        <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                     samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
        </mixPort>
        <mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT" />
        <mixPort name="tunnel" role="source"
                 flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
   </mixPorts>
   <devicePorts>
        <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink" />
        <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink"
                    encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" />
    </devicePorts>
    <routes>
        <route type="mix" sink="Speaker" sources="primary output"/>
        <route type="mix" sink="Out Aux Digital" sources="primary output,direct,tunnel"/>
    </routes>
</module>

आपके पास स्टैटिक चैनल मास्क तय करने का विकल्प भी होता है, जैसे कि AUDIO_CHANNEL_OUT_5POINT1. AudioFlinger का मिक्सर, कॉन्टेंट को स्टीरियो में अपने-आप डाउनमिक्स कर देता है. ऐसा तब होता है, जब कॉन्टेंट को किसी ऐसे ऑडियो डिवाइस पर भेजा जाता है जो मल्टीचैनल ऑडियो के साथ काम नहीं करता.

मीडिया कोडेक

पक्का करें कि आपके हार्डवेयर और ड्राइवर के साथ काम करने वाले ऑडियो कोडेक, आपके प्रॉडक्ट के लिए सही तरीके से बताए गए हों. ज़्यादा जानकारी के लिए, फ़्रेमवर्क के लिए कोडेक एक्सपोज़ करना देखें.