חיבור מכשיר קלט ב-AAOS

אפשר להשתמש במנגנונים האלה כדי להפעיל אודיו ב-Android:

כל מנגנון מאפשר הפעלת אודיו ב-Android. יכול להיות שהאפשרויות האלה לא יספיקו להפעלת רדיו או להפעלה ממכשירי קלט, אבל אפשר לשלב כל אחת מהן עם לכידת אודיו או עם המחלקה MediaRecorder כדי קודם ללכוד את האודיו ואז להפעיל אותו מ-Android. במיוחד באפליקציות של המערכת, אפשר להשתמש במידע הבא כדי לחבר מכשיר קלט למיקסר פלט ב-AAOS.

נגן HwAudioSource

HwAudioSource מחבר את המכשיר שממנו מופעל האודיו ישירות למיקסר של Android.

גורמים מניעים

יכולות להיות כמה מגבלות כשמשתמשים ב-Android בתיקון של אודיו בחומרה או בהעברה ממכשיר למכשיר. כל אחת מהאפשרויות האלה לא יכולה לקבל אירועים של מקשי מדיה כמו PLAY,‏ PAUSE ו-STOP. בנוסף, מכיוון שהן עוקפות את מחסנית האודיו של 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();

שינויים ב-HAL של אודיו

כדאי לקחת בחשבון את הציפיות הבאות לגבי HAL של אודיו עם הנגן החדש הזה. לדוגמה, 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_DEVICE_IN_FM_TUNER ב-audio_policy_configuration.xml:

<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>

בעזרת הגדרת המכשיר הזו, אפשר למצוא את מכשיר הקלט של רדיו FM באמצעות AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS בשילוב עם AudioDeviceInfo.TYPE_FM_TUNER.

יצירת תיקוני אודיו

אפשר ליצור תיקון אודיו בין שתי יציאות אודיו, בין אם מדובר ביציאת מיקס או ביציאת מכשיר. בדרך כלל, תיקון אודיו מיציאת המיקס ליציאת המכשיר מיועד להפעלה, והכיוון ההפוך מיועד ללכידה.

לדוגמה, תיקון אודיו שמנתב דגימות אודיו מFM_TUNER מקור ישירות ל-media sink עוקף את מיקסר התוכנה. לאחר מכן צריך להשתמש במיקסר חומרה כדי לערבב את דגימות האודיו מ-Android ומ-FM_TUNER עבור יעד הפלט. כשיוצרים תיקון אודיו ישירות מFM_TUNER המקור אל יעד המדיה:

  • השליטה בעוצמת הקול חלה על יעד המדיה וצריכה להשפיע על האודיו ב-Android וב-FM_TUNER.

  • המשתמשים יכולים לעבור בין Android לבין FM_TUNER אודיו באמצעות מעבר פשוט בין האפליקציות (אין צורך לבחור מקור מדיה ספציפי).

יכול להיות שיישומים לרכב יצטרכו גם ליצור תיקון אודיו בין שני יציאות של מכשיר. כדי לעשות את זה, קודם צריך להצהיר על יציאות המכשיר ועל המסלולים האפשריים ב-audio_policy_configuration.xml ואז לשייך את יציאות המכשיר ל-mixports.

הגדרה לדוגמה

אפשר לעיין בהגדרות לדוגמה האלה: 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>

Audio driver API

אפשר להשתמש ב-getExternalSources() כדי לאחזר רשימה של מקורות זמינים (מזוהים לפי כתובת), ואז ליצור תיקוני אודיו בין המקורות האלה לבין יציאות היעד לפי שימושים באודיו. נקודות הכניסה המתאימות ב-Audio HAL מופיעות ב-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

פרטים על פיתוח אפליקציית רדיו זמינים במאמר בנושא הטמעת רדיו.