Kết nối thiết bị đầu vào trong AAOS

Bạn có thể sử dụng các cơ chế này để phát âm thanh trong Android:

Mỗi cơ chế cho phép phát lại âm thanh trong Android. Để phát lại radio hoặc phát lại từ các thiết bị đầu vào, các tùy chọn này có thể không đủ, mặc dù mỗi tùy chọn có thể được kết hợp với tính năng thu âm hoặc lớp MediaRecorder để trước tiên ghi lại âm thanh rồi phát lại từ Android. Đối với các ứng dụng hệ thống nói riêng, thông tin sau có thể được sử dụng để kết nối thiết bị đầu vào với bộ trộn đầu ra trong AAOS.

Trình phát HwAudioSource

HwAudioSource kết nối trực tiếp thiết bị nguồn âm thanh với bộ trộn Android.

Động lực

Một số hạn chế có thể phát sinh khi sử dụng bản vá âm thanh giữa các thiết bị hoặc phần cứng với Android. Mỗi tùy chọn không thể nhận các sự kiện quan trọng về phương tiện như PLAY , PAUSESTOP , đồng thời vì chúng phá vỡ ngăn xếp âm thanh của Android nên mỗi tùy chọn đều yêu cầu phần cứng để trộn bản vá vào âm thanh khác từ Android.

Sử dụng HwAudioSource

HwAudioSource là một loại trình phát mới được thiết kế dưới dạng bản vá phần mềm. Điều này cho phép các ứng dụng sử dụng trình phát này nhận các sự kiện chính về phương tiện cũng như luồng đầu ra được Android trộn và định tuyến.

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

Thay đổi âm thanh HAL

Với trình phát mới này, hãy cân nhắc những kỳ vọng này đối với âm thanh HAL. Ví dụ: device/generic/car/emulator/audio/driver/audio_hw.c .

  • adev_create_audio_patch mong đợi yêu cầu thiết lập bản vá âm thanh từ thiết bị đến bộ trộn.

  • adev_open_input_stream mong muốn audio_sourceAUDIO_SOURCE_FM_TUNER .

  • in_read lấp đầy bộ đệm âm thanh bằng dữ liệu âm thanh radio phát sóng.

Chúng tôi khuyên bạn nên định cấu hình thiết bị dò kênh có loại AUDIO_DEVICE_IN_FM_TUNER trong 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>

Với cấu hình thiết bị này, bạn có thể tạo điều kiện thuận lợi cho việc tìm kiếm thiết bị đầu vào đài FM bằng cách sử dụng AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS kết hợp với AudioDeviceInfo.TYPE_FM_TUNER .

Tạo bản vá âm thanh

Bạn có thể tạo bản vá âm thanh giữa hai cổng âm thanh, cổng trộn hoặc cổng thiết bị. Thông thường, bản vá âm thanh từ cổng trộn đến cổng thiết bị là để phát lại trong khi hướng ngược lại là để ghi.

Ví dụ: bản vá âm thanh định tuyến các mẫu âm thanh từ nguồn FM_TUNER trực tiếp đến bộ thu phương tiện sẽ bỏ qua bộ trộn phần mềm. Sau đó, bạn phải sử dụng bộ trộn phần cứng để trộn các mẫu âm thanh từ Android và FM_TUNER cho bồn rửa. Khi tạo bản vá âm thanh trực tiếp từ nguồn FM_TUNER tới ổ chứa phương tiện:

  • Điều khiển âm lượng áp dụng cho vùng chứa phương tiện và sẽ ảnh hưởng đến cả âm thanh Android và FM_TUNER .

  • Người dùng có thể chuyển đổi giữa âm thanh Android và FM_TUNER thông qua chuyển đổi ứng dụng đơn giản (không cần lựa chọn nguồn phương tiện rõ ràng).

Việc triển khai ô tô cũng có thể cần tạo bản vá âm thanh giữa hai cổng thiết bị. Để làm như vậy, trước tiên bạn phải khai báo các cổng thiết bị và các tuyến có thể có trong audio_policy_configuration.xml , sau đó liên kết các cổng kết hợp với các cổng thiết bị.

Cấu hình mẫu

Xem cấu hình mẫu này, 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>

API trình điều khiển âm thanh

Bạn có thể sử dụng getExternalSources() để truy xuất danh sách các nguồn có sẵn (được xác định theo địa chỉ), sau đó tạo các bản vá âm thanh giữa các nguồn này và cổng chìm theo cách sử dụng âm thanh. Các điểm vào tương ứng trên Audio HAL xuất hiện trong 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);
...
}

Bộ dò đài

Khi xây dựng ứng dụng radio, chúng tôi khuyên bạn nên sử dụng HwAudioSource vì nó xử lý cả việc tạo bản vá cũng như phiên phương tiện để xử lý các sự kiện quan trọng của phương tiện. Có thể tạo nhiều nguồn âm thanh cho cùng một thuộc tính nguồn và âm thanh. Có thể có một cái để sử dụng radio thường xuyên cũng như cái thứ hai để thông báo giao thông.

Nếu ghi FM_TUNER , trong Android 11, quyền thực hiện đã được đổi thành android.permission.CAPTURE_AUDIO_OUTPUT . Nó không còn trải qua quá trình kiểm tra quyền OP_RECORD_AUDIO vốn chỉ áp dụng cho micrô. Điều này sẽ không ảnh hưởng đến ứng dụng vì FM_TUNER đã yêu cầu quyền SYSTEM_API để truy cập.

Xem Triển khai radio để biết chi tiết về cách xây dựng ứng dụng radio.