חיבור מכשיר לקליטת נתונים ב-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();

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

בנגן החדש הזה, כדאי לשקול את הציפיות הבאות ל-HAL של האודיו. לדוגמה, device/generic/car/emulator/audio/driver/audio_hw.c.

  • adev_create_audio_patch מצפה שהבקשה תיצור תיקון אודיו ממכשיר למיקסר.

  • לפרמטר adev_open_input_stream צפוי להיות הערך audio_sourceAUDIO_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 ישירות לבורר המדיה, עוקף את המיקסר של התוכנה. לאחר מכן צריך להשתמש במיקסר חומרה כדי לערבב את דגימות האודיו מ-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>

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 גישה.

במאמר הטמעת רדיו מוסבר איך יוצרים אפליקציית רדיו.