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

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

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

Có thể xảy ra một số hạn chế khi sử dụng bản vá âm thanh phần cứng hoặc thiết bị với thiết bị trên Android. Mỗi tuỳ chọn không thể nhận các sự kiện phím đa phương tiện như PHÁT, TẠM DỪNGDỪNG. Ngoài ra, vì các tuỳ chọn này lách qua ngăn xếp âm thanh của Android, nên mỗi tuỳ chọn đều yêu cầu phần cứng để kết hợp 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 sự kiện nhấn phím đa phương tiện và luồng đầu ra được Android kết hợp 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 đối với HAL âm thanh

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

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

  • adev_open_input_stream dự kiến audio_source sẽ là AUDIO_SOURCE_FM_TUNER.

  • in_read điền dữ liệu âm thanh phát thanh truyền tin vào bộ đệm âm thanh.

Bạn nên định cấu hình thiết bị bộ thu sóng 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ể hỗ trợ việc tì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 một bản vá âm thanh giữa hai cổng âm thanh, cổng kết hợp hoặc cổng thiết bị. Thông thường, bản vá âm thanh từ cổng kết hợp đến cổng thiết bị là để phát, còn hướng ngược lại là để ghi lại.

Ví dụ: một 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ồn lưu trữ nội dung đa phương tiện, bỏ qua bộ trộn phần mềm. Sau đó, bạn phải sử dụng trình trộn phần cứng để trộn các mẫu âm thanh từ Android và FM_TUNER cho bồn lưu trữ. Khi tạo bản vá âm thanh trực tiếp từ nguồn FM_TUNER đến bồn lưu trữ nội dung đa phương tiện:

  • Chế độ điều khiển âm lượng áp dụng cho bồn lưu trữ nội dung nghe nhì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 một nút chuyển ứng dụng đơn giản (không cần chọn nguồn nội dung nghe nhìn rõ ràng).

Việc triển khai trong ô tô cũng có thể cần tạo một 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 bồn lưu trữ theo mức sử dụng âm thanh. Các điểm truy cập 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ộ thu sóng

Khi xây dựng ứng dụng đài phát thanh, bạn nên sử dụng HwAudioSource vì lớp này xử lý cả việc tạo bản vá cũng như một phiên phát nội dung đa phương tiện để xử lý các sự kiện phím đa phương tiện. Bạn có thể tạo nhiều nguồn âm thanh cho cùng một nguồn và thuộc tính âm thanh. Bạn có thể có một kênh để sử dụng đài thông thường và một kênh thứ hai để thông báo về tình hình giao thông.

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

Xem phần Triển khai đài phát thanh để biết thông tin chi tiết về cách tạo ứng dụng đài phát thanh.