AAOS में इनपुट डिवाइस को कनेक्ट करना

Android में ऑडियो चलाने के लिए, इन तरीकों का इस्तेमाल किया जा सकता है:

हर तरीके से, Android में ऑडियो चलाया जा सकता है. रेडियो पर ऑडियो चलाने या इनपुट डिवाइसों से ऑडियो चलाने के लिए, ये विकल्प शायद काम के न हों. हालांकि, इनमें से किसी भी विकल्प को ऑडियो कैप्चर या MediaRecorder क्लास के साथ जोड़ा जा सकता है, ताकि पहले ऑडियो कैप्चर किया जा सके और फिर उसे Android पर चलाया जा सके. खास तौर पर, सिस्टम ऐप्लिकेशन के लिए, इस जानकारी का इस्तेमाल करके AAOS में इनपुट डिवाइस को आउटपुट मिक्सर से कनेक्ट किया जा सकता है.

HwAudioSource प्लेयर

HwAudioSource, ऑडियो सोर्स डिवाइस को सीधे Android मिक्सर से कनेक्ट करता है.

मोटिवेशन

Android के साथ डिवाइस-टू-डिवाइस या हार्डवेयर ऑडियो पैच का इस्तेमाल करने पर, कई सीमाएं आ सकती हैं. हर विकल्प को चलाएं, रोकें, और बंद करें जैसे मीडिया की मुख्य इवेंट नहीं मिलते. साथ ही, ये Android के ऑडियो स्टैक को गच्चा देते हैं. इसलिए, हर विकल्प को Android के दूसरे ऑडियो में पैच को मिक्स करने के लिए हार्डवेयर की ज़रूरत होती है.

HwAudioSource का इस्तेमाल करना

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

mHwAudioSource = new HwAudioSource.Builder()
                .setAudioDeviceInfo(AudioDeviceInfo: info)
                .setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build())
                .build();
mHwAudioSource.play();
mHwAudioSource.stop();

ऑडियो एचएएल में हुए बदलाव

इस नए प्लेयर के साथ, ऑडियो एचएएल के लिए इन उम्मीदों पर विचार करें. उदाहरण के लिए, device/generic/car/emulator/audio/driver/audio_hw.c.

  • adev_create_audio_patch को किसी डिवाइस से मिक्सर पर ऑडियो पैच सेट अप करने का अनुरोध मिलता है.

  • adev_open_input_stream के लिए audio_source का वैल्यू AUDIO_SOURCE_FM_TUNER होना चाहिए.

  • in_read, ब्रॉडकास्ट रेडियो के ऑडियो डेटा से ऑडियो बफ़र को भरता है.

हमारा सुझाव है कि आप audio_policy_configuration.xml में AUDIO_DEVICE_IN_FM_TUNER टाइप वाले ट्यूनर डिवाइस को कॉन्फ़िगर करें:

<devicePort
    tagName="Tuner_source"
    type="AUDIO_DEVICE_IN_FM_TUNER"
    role="source"
    address="tuner0">
    <profile
        name=""
        format="AUDIO_FORMAT_PCM_16_BIT"
        samplingRates="48000"
        channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</devicePort>

इस डिवाइस कॉन्फ़िगरेशन की मदद से, AudioDeviceInfo.TYPE_FM_TUNER के साथ AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS का इस्तेमाल करके, एफ़एम रेडियो इनपुट डिवाइस को ढूंढा जा सकता है.

ऑडियो पैच बनाना

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

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

  • वॉल्यूम कंट्रोल, मीडिया सिंक पर लागू होता है. इसका असर Android और FM_TUNER, दोनों के ऑडियो पर पड़ना चाहिए.

  • उपयोगकर्ता, ऐप्लिकेशन को स्विच करके Android और FM_TUNER ऑडियो के बीच आसानी से स्विच कर सकते हैं. इसके लिए, मीडिया सोर्स को साफ़ तौर पर चुनने की ज़रूरत नहीं है.

वाहन में लागू करने के लिए, हो सकता है कि दो डिवाइस पोर्ट के बीच ऑडियो पैच भी बनाना पड़े. ऐसा करने के लिए, आपको पहले audio_policy_configuration.xml में डिवाइस के पोर्ट और संभावित रूट की जानकारी देनी होगी. इसके बाद, डिवाइस के पोर्ट के साथ मिक्सपोर्ट जोड़ने होंगे.

सैंपल कॉन्फ़िगरेशन

सैंपल कॉन्फ़िगरेशन देखें, device/generic/car/emulator/audio/audio_policy_configuration.xml.

<audioPolicyConfiguration>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_media_out</item>
                <item>bus1_audio_patch_test_in</item>
            </attachedDevices>
            <mixPorts>
                <mixPort name="mixport_bus0_media_out" 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="mixport_audio_patch_in" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                           samplingRates="48000"
                           channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
                        address="bus0_media_out">
                    <profile balance="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
                <devicePort tagName="bus1_audio_patch_test_in" type="AUDIO_DEVICE_IN_BUS" role="source"
                        address="bus1_audio_patch_test_in">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out,bus1_audio_patch_test_in"/>
                <route type="mix" sink="mixport_audio_patch_in" sources="bus1_audio_patch_test_in"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>

ऑडियो ड्राइवर एपीआई

getExternalSources() का इस्तेमाल करके, उपलब्ध सोर्स (पते से पहचाने जाते हैं) की सूची देखी जा सकती है. इसके बाद, ऑडियो के इस्तेमाल के हिसाब से इन सोर्स और सिंक पोर्ट के बीच ऑडियो पैच बनाए जा सकते हैं. ऑडियो एचएएल के संबंधित एंट्री पॉइंट, IDevice.hal में दिखते हैं:

Interface IDevice {
...
/
*   Creates an audio patch between several source and sink ports.  The handle
*   is allocated by the HAL and must be unique for this audio HAL module.
*
*   @param sources patch sources.
*   @param sinks patch sinks.
*   @return retval operation completion status.
*   @return patch created patch handle.
*/
createAudioPatch(vec<AudioPortConfig> sources, vec<AudioPortConfig> sinks)
       generates (Result retval, AudioPatchHandle patch);

*   Release an audio patch.
*
*   @param patch patch handle.
*   @return retval operation completion status.
*/
releaseAudioPatch(AudioPatchHandle patch) generates (Result retval);
...
}

रेडियो ट्यूनर

हमारा सुझाव है कि रेडियो ऐप्लिकेशन बनाते समय, HwAudioSource का इस्तेमाल करें. ऐसा इसलिए, क्योंकि यह पैच बनाने के साथ-साथ मीडिया सेशन को भी मैनेज करता है, ताकि मीडिया की कुंजी से जुड़े इवेंट मैनेज किए जा सकें. एक ही सोर्स और ऑडियो एट्रिब्यूट के लिए, कई ऑडियो सोर्स बनाए जा सकते हैं. रेडियो के सामान्य इस्तेमाल के लिए एक और ट्रैफ़िक की सूचनाओं के लिए दूसरा, दोनों तरह के स्टेशन सेट किए जा सकते हैं.

अगर FM_TUNER को रिकॉर्ड किया जा रहा है, तो Android 11 में, रिकॉर्ड करने की अनुमति को android.permission.CAPTURE_AUDIO_OUTPUT में बदल दिया गया था. अब यह OP_RECORD_AUDIO अनुमति की जांच से नहीं गुज़रता, जो सिर्फ़ माइक्रोफ़ोन पर लागू होता है. इससे ऐप्लिकेशन पर कोई असर नहीं पड़ेगा, क्योंकि FM_TUNER को पहले से ही ऐक्सेस के लिए SYSTEM_API की अनुमति चाहिए होती है.

रेडियो ऐप्लिकेशन बनाने के बारे में जानकारी के लिए, रेडियो लागू करना देखें.