您可以使用下列機制在 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_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>
透過這項裝置設定,您可以使用 AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS
搭配 AudioDeviceInfo.TYPE_FM_TUNER
,輕鬆找到 FM 收音機輸入裝置。
建立音訊修補程式
您可以在兩個音訊連接埠之間建立音訊修補程式,可以是混音連接埠或裝置連接埠。一般來說,從混音埠到裝置埠的音訊修補程式用於播放,反向則用於擷取。
舉例來說,如果音訊修補程式將音訊樣本從 FM_TUNER
來源直接傳送至媒體接收器,就會略過軟體混音器。然後,您必須使用硬體混音器,混合 Android 和 FM_TUNER
的音訊樣本,以供接收器使用。直接從 FM_TUNER
來源建立音訊修補程式至媒體接收器時:
音量控制適用於媒體接收器,應會影響 Android 和
FM_TUNER
音訊。使用者只要切換應用程式,即可在 Android 和
FM_TUNER
音訊之間切換 (無需明確選擇媒體來源)。
汽車實作項目可能也需要在兩個裝置連接埠之間建立音訊修補程式。如要這麼做,您必須先在 audio_policy_configuration.xml
中宣告裝置通訊埠和可能的路徑,然後將 mixport 與裝置通訊埠建立關聯。
範例設定
請參閱這個設定範例: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
您可以使用 getExternalSources()
擷取可用來源清單 (依地址識別),然後依音訊用途在這些來源和接收器通訊埠之間建立音訊修補程式。音訊 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
要求權限,因此這項異動對應用程式應不會造成影響。
如要進一步瞭解如何建構電台應用程式,請參閱「實作電台」。