使 Android 使用新的音频 HAL 需要什么
What is required to make Android use a new Audio HAL
我正在编写一个新的 Android 音频 HAL,让我的应用程序将音频馈送到其他应用程序,让我的手持远程麦克风输入到达 Google 应用程序。本质上,虚拟音频线。
这是一项正在进行的工作。
我可能会覆盖 AUDIO_DEVICE_IN_BACK_MIC,但这是开放的建议。
我对如何确保 Android 使用此 HAL 进行输入有疑问。
我需要替换 audio.primary.default.so 还是应该保留 audio.vcable.default.so?
更具体地说:如果我不替换主要的,Android 如何知道使用我的 HAL 而不是主要的?
更新:
我真的可以在这项工作中得到任何帮助。任何指针都有帮助。
我写了一个Audio HAL模块。我在 audio_policy.conf 中添加了以下(粗体项):
全球:
global_configuration {
attached_output_devices AUDIO_DEVICE_OUT_SPEAKER|**AUDIO_DEVICE_OUT_LINE**
default_output_device AUDIO_DEVICE_OUT_SPEAKER
attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX|**AUDIO_DEVICE_IN_LINE**
}
及audio_hw_modules
以下
vloop {
inputs {
vloop {
sampling_rates 16000
channel_masks AUDIO_CHANNEL_IN_MONO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_IN_LINE
}
}
outputs {
vloop {
sampling_rates 16000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_LINE
flags AUDIO_OUTPUT_FLAG_DIRECT
}
}
}
我还在 AudioFlinger.cpp
中添加了以下内容(粗体)
static const char * const audio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,
AUDIO_HARDWARE_MODULE_ID_A2DP,
AUDIO_HARDWARE_MODULE_ID_USB,
**AUDIO_HARDWARE_MODULE_ID_VLOOP**
};
我可以看到在启动过程中,我的 HAL 被加载了,我得到了这些日志:
10-06 06:14:40.365 194-194/? I/AudioFlinger: Using default 3000 mSec as standby time.
10-06 06:14:46.664 194-194/? I/AudioPolicyService: AudioPolicyService CSTOR in new mode
10-06 06:14:46.673 194-194/? I/APM::ConfigParsingUtils: loadAudioPolicyConfig() loaded /system/etc/audio_policy.conf
10-06 06:14:46.681 194-194/? D/audio_hw_primary: adev_open: enter
10-06 06:14:46.797 194-194/? I/AudioFlinger: loadHwModule() Loaded primary audio interface from QCOM Audio HAL (audio) handle 1
10-06 06:14:46.797 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 2
10-06 06:14:46.797 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1
10-06 06:14:46.798 194-194/? I/AudioFlinger: HAL output buffer size 240 frames, normal sink buffer size 960 frames
10-06 06:14:46.813 194-194/? I/AudioFlinger: Using module 1 has the primary audio interface
10-06 06:14:46.816 194-607/? I/AudioFlinger: AudioFlinger's thread 0xb4140000 ready to run
10-06 06:14:46.816 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:14:46.818 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 8
10-06 06:14:46.818 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1
10-06 06:14:46.818 194-194/? I/AudioFlinger: HAL output buffer size 960 frames, normal sink buffer size 960 frames
10-06 06:14:46.818 194-608/? I/AudioFlinger: AudioFlinger's thread 0xb3dc0000 ready to run
10-06 06:14:46.818 194-607/? E/AudioFlinger: no wake lock to update!
10-06 06:14:46.818 194-608/? D/audio_hw_primary: out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2
10-06 06:14:46.818 194-608/? E/AudioFlinger: no wake lock to update!
10-06 06:14:46.820 194-609/? I/AudioFlinger: AudioFlinger's thread 0xb3c40000 ready to run
10-06 06:14:46.823 194-194/? I/AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 7
10-06 06:14:46.828 194-194/? I/AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 8
10-06 06:14:46.832 194-194/? I/r_submix: adev_open(name=audio_hw_if)
10-06 06:14:46.832 194-194/? I/AudioFlinger: loadHwModule() Loaded r_submix audio interface from Wifi Display audio HAL (audio) handle 9
10-06 06:14:46.832 194-194/? D/r_submix: submix_audio_device_create_pipe_l(addr=0, idx=9)
10-06 06:14:46.833 194-610/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_release_pipe_l(idx=9) addr=0
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_destroy_pipe_l(): pipe destroyed
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open: audio_hw_if
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1678
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1685
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1688
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1722
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_init_check(): 1252
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_volume: 1.000000
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_mute: 0
10-06 06:14:46.835 194-194/? I/AudioFlinger: loadHwModule() Loaded vloop audio interface from UI_audio_HW_HAL (audio) handle 11
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open_input_stream(): 1490
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_sample_rate(): 979
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_sample_rate(): 979
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.838 194-613/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:14:46.838 194-194/? D/audio_vloop: adev_close_input_stream(): 1570
10-06 06:14:46.839 194-194/? W/APM::AudioPolicyManager: Input device 00020000 unreachable
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 216: Entered
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 366: Exiting
10-06 06:15:07.137 616-616/? I/InputManager: Initializing input manager, mUseDevInputEventForAudioJack=false
10-06 06:15:10.155 616-616/? I/SystemServer: Audio Service
10-06 06:15:10.222 194-607/? E/AudioFlinger: no wake lock to update!
10-06 06:15:10.222 194-608/? E/AudioFlinger: no wake lock to update!
10-06 06:15:10.224 194-614/? D/audio_hw_primary: adev_set_mic_mute: state 0
10-06 06:15:10.224 194-614/? D/audio_vloop: adev_set_mic_mute: 0
10-06 06:15:14.061 194-614/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false
10-06 06:15:14.061 194-614/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false]
10-06 06:15:14.084 194-194/? I/AudioFlinger: systemReady
10-06 06:15:16.308 194-194/? D/audio_hw_primary: adev_set_mic_mute: state 0
10-06 06:15:16.308 194-194/? D/audio_vloop: adev_set_mic_mute: 0
10-06 06:15:17.072 194-194/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false
10-06 06:15:17.072 194-194/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false]
10-06 06:15:25.023 733-733/? W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz
10-06 06:15:25.032 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:25.043 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
10-06 06:15:25.043 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker)
10-06 06:15:25.050 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback
10-06 06:15:26.431 1150-1298/? I/MicrophoneInputStream: mic_starting com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.443 194-1585/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:15:26.447 1150-1298/? I/MicrophoneInputStream: mic_started com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic)
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:26.460 194-1585/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record
10-06 06:15:26.942 1150-1271/? I/AudioController: internalShutdown
10-06 06:15:26.943 1150-1271/? I/MicrophoneInputStream: mic_close com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.943 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read
10-06 06:15:26.986 194-1585/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record
10-06 06:15:26.987 194-1585/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:27.066 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:27.100 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(7)
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker)
10-06 06:15:30.262 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:30.272 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
10-06 06:15:30.273 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker)
10-06 06:15:30.280 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback
10-06 06:15:30.347 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(10)
10-06 06:15:31.517 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:31.751 1150-1298/? I/MicrophoneInputStream: mic_starting com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:31.762 194-1826/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:15:31.771 1150-1298/? I/MicrophoneInputStream: mic_started com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic)
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:31.783 194-1826/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker)
10-06 06:15:34.850 1150-1271/? I/AudioController: internalShutdown
10-06 06:15:34.851 1150-1271/? I/MicrophoneInputStream: mic_close com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:34.851 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic)
我的是 audio_vloop。我可以看到 Android 打开我的设备,然后打开输入流,然后关闭输入流。它从不尝试打开输出流。 audio_vloop 实现了输入和输出流。此后,audio_vloop 中的任何内容都不会被 Android 调用。
我制作了一个播放音频的小应用程序(目前来自 pcm 文件)。我想将此输出重定向到我的 HAL。为了实现这一点,我相信我需要在我的音轨上做一个 AudioTrack.setPreferredDevice() 。我发现音频管理器应该有所有音频设备的列表。
所以我打电话给:
AudioDeviceInfo aDevInfo[] = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
它只找到 1 个设备,有关此设备的更多信息:
10-06 06:37:01.962 3295-3663/? D/AudioPlayer: Have [1] devices
10-06 06:37:01.964 3295-3663/? D/AudioPlayer: devInfo[0]: [Landroid.media.AudioDeviceInfo;@90bd9da
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getProductName()AOSP on Flo
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getType()2
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSink()true
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSource()false
这貌似是我没有实现的audioPort。所以它不是来自我的 HAL。
在 Android 允许我的应用程序与我的设备对话之前,我显然错过了一个或多个步骤。
我需要能够将音频从我的应用程序发送到我的 HAL。
稍后,我还需要能够从我的 HAL 接收音频(通过 AudioRecord 等)。
在将我的 HAL 集成到 Android 中时我遗漏了什么?
我需要实现音频端口吗?
还需要其他东西吗?
更新 2
我发现 AOSP 中有错别字,在 AudioPolicyManager.cpp@2922
而不是 Output
,它打印 Input
我有这个日志 AudioPolicyManager: Input device 00020000 unreachable
,假设它在谈论 BT/A2DP 输入设备,我忽略了它。
我修复了我设备的日志,原来是我们要使用的线路输出设备。我现在正在调试这个方向
找到答案。
对于输出流:
- 不支持
AUDIO_CHANNEL_OUT_STEREO
的输出未被 Android 打开
提及标志 AUDIO_OUTPUT_FLAG_DIRECT
的输出不会被 Android 自动打开。这在 AudioPolicyManager.cpp
中的以下代码中很明显
if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
}
来自 here
可能有一种以编程方式打开它们的方法,但我还没有找到答案。
这两个一旦修复就足以让 Android 开始使用我的输出流。
在流中:
流中已经是 AudioManager.getDevices()
结果的一部分
因此可以在 AudioTrack.setPreferredDevice()
之后从流中的 vloop 中读取。
为了确保其他应用程序能够从 vloop 读取麦克风输入,我不得不声明它来实现 AUDIO_DEVICE_IN_BUILTIN_MIC
。为此,我还在 audio_policy.conf
.
中从主 HAL 中删除了 AUDIO_DEVICE_IN_BUILTIN_MIC
此外,我在流立体声中制作只是为了保持与流缓冲区格式的兼容性。
经过这些改动,我看到vloop不断有读写调用。
更新:
我后来发现上述行为取决于音频策略管理器的实现。他们中的大多数行为相同,(例如,大多数打开 INBUILT_MIC 用于 VOICE_RECOGNITION 输入)但有些可能不是(Nexus Player)对于这些异常值,要么实施他们的 APM 打开的内容,要么修改 APM 以打开你的HAL 实现.
我正在编写一个新的 Android 音频 HAL,让我的应用程序将音频馈送到其他应用程序,让我的手持远程麦克风输入到达 Google 应用程序。本质上,虚拟音频线。
这是一项正在进行的工作。 我可能会覆盖 AUDIO_DEVICE_IN_BACK_MIC,但这是开放的建议。
我对如何确保 Android 使用此 HAL 进行输入有疑问。
我需要替换 audio.primary.default.so 还是应该保留 audio.vcable.default.so?
更具体地说:如果我不替换主要的,Android 如何知道使用我的 HAL 而不是主要的?
更新:
我真的可以在这项工作中得到任何帮助。任何指针都有帮助。
我写了一个Audio HAL模块。我在 audio_policy.conf 中添加了以下(粗体项):
全球:
global_configuration {
attached_output_devices AUDIO_DEVICE_OUT_SPEAKER|**AUDIO_DEVICE_OUT_LINE**
default_output_device AUDIO_DEVICE_OUT_SPEAKER
attached_input_devices AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_BACK_MIC|AUDIO_DEVICE_IN_REMOTE_SUBMIX|**AUDIO_DEVICE_IN_LINE**
}
及audio_hw_modules
以下 vloop {
inputs {
vloop {
sampling_rates 16000
channel_masks AUDIO_CHANNEL_IN_MONO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_IN_LINE
}
}
outputs {
vloop {
sampling_rates 16000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_LINE
flags AUDIO_OUTPUT_FLAG_DIRECT
}
}
}
我还在 AudioFlinger.cpp
中添加了以下内容(粗体)static const char * const audio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,
AUDIO_HARDWARE_MODULE_ID_A2DP,
AUDIO_HARDWARE_MODULE_ID_USB,
**AUDIO_HARDWARE_MODULE_ID_VLOOP**
};
我可以看到在启动过程中,我的 HAL 被加载了,我得到了这些日志:
10-06 06:14:40.365 194-194/? I/AudioFlinger: Using default 3000 mSec as standby time.
10-06 06:14:46.664 194-194/? I/AudioPolicyService: AudioPolicyService CSTOR in new mode
10-06 06:14:46.673 194-194/? I/APM::ConfigParsingUtils: loadAudioPolicyConfig() loaded /system/etc/audio_policy.conf
10-06 06:14:46.681 194-194/? D/audio_hw_primary: adev_open: enter
10-06 06:14:46.797 194-194/? I/AudioFlinger: loadHwModule() Loaded primary audio interface from QCOM Audio HAL (audio) handle 1
10-06 06:14:46.797 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 2
10-06 06:14:46.797 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1
10-06 06:14:46.798 194-194/? I/AudioFlinger: HAL output buffer size 240 frames, normal sink buffer size 960 frames
10-06 06:14:46.813 194-194/? I/AudioFlinger: Using module 1 has the primary audio interface
10-06 06:14:46.816 194-607/? I/AudioFlinger: AudioFlinger's thread 0xb4140000 ready to run
10-06 06:14:46.816 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:14:46.818 194-194/? I/AudioFlinger: openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 8
10-06 06:14:46.818 194-194/? I/AudioFlinger: AudioStreamOut::open(), mHalFormatIsLinearPcm = 1
10-06 06:14:46.818 194-194/? I/AudioFlinger: HAL output buffer size 960 frames, normal sink buffer size 960 frames
10-06 06:14:46.818 194-608/? I/AudioFlinger: AudioFlinger's thread 0xb3dc0000 ready to run
10-06 06:14:46.818 194-607/? E/AudioFlinger: no wake lock to update!
10-06 06:14:46.818 194-608/? D/audio_hw_primary: out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2
10-06 06:14:46.818 194-608/? E/AudioFlinger: no wake lock to update!
10-06 06:14:46.820 194-609/? I/AudioFlinger: AudioFlinger's thread 0xb3c40000 ready to run
10-06 06:14:46.823 194-194/? I/AudioFlinger: loadHwModule() Loaded a2dp audio interface from A2DP Audio HW HAL (audio) handle 7
10-06 06:14:46.828 194-194/? I/AudioFlinger: loadHwModule() Loaded usb audio interface from USB audio HW HAL (audio) handle 8
10-06 06:14:46.832 194-194/? I/r_submix: adev_open(name=audio_hw_if)
10-06 06:14:46.832 194-194/? I/AudioFlinger: loadHwModule() Loaded r_submix audio interface from Wifi Display audio HAL (audio) handle 9
10-06 06:14:46.832 194-194/? D/r_submix: submix_audio_device_create_pipe_l(addr=0, idx=9)
10-06 06:14:46.833 194-610/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_release_pipe_l(idx=9) addr=0
10-06 06:14:46.833 194-194/? D/r_submix: submix_audio_device_destroy_pipe_l(): pipe destroyed
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open: audio_hw_if
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1678
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1685
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1688
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open(): 1722
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_init_check(): 1252
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_volume: 1.000000
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_set_master_mute: 0
10-06 06:14:46.835 194-194/? I/AudioFlinger: loadHwModule() Loaded vloop audio interface from UI_audio_HW_HAL (audio) handle 11
10-06 06:14:46.835 194-194/? D/audio_vloop: adev_open_input_stream(): 1490
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_sample_rate(): 979
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.835 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size(): 1005
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_buffer_size: 1600
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format(): 1029
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_format: 0x00000001
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_sample_rate(): 979
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels(): 1017
10-06 06:14:46.836 194-194/? D/audio_vloop: in_get_channels: 0x00000001
10-06 06:14:46.838 194-613/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:14:46.838 194-194/? D/audio_vloop: adev_close_input_stream(): 1570
10-06 06:14:46.839 194-194/? W/APM::AudioPolicyManager: Input device 00020000 unreachable
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 216: Entered
10-06 06:14:46.839 194-611/? D/audio_vloop: looper_thread(): 366: Exiting
10-06 06:15:07.137 616-616/? I/InputManager: Initializing input manager, mUseDevInputEventForAudioJack=false
10-06 06:15:10.155 616-616/? I/SystemServer: Audio Service
10-06 06:15:10.222 194-607/? E/AudioFlinger: no wake lock to update!
10-06 06:15:10.222 194-608/? E/AudioFlinger: no wake lock to update!
10-06 06:15:10.224 194-614/? D/audio_hw_primary: adev_set_mic_mute: state 0
10-06 06:15:10.224 194-614/? D/audio_vloop: adev_set_mic_mute: 0
10-06 06:15:14.061 194-614/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false
10-06 06:15:14.061 194-614/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false]
10-06 06:15:14.084 194-194/? I/AudioFlinger: systemReady
10-06 06:15:16.308 194-194/? D/audio_hw_primary: adev_set_mic_mute: state 0
10-06 06:15:16.308 194-194/? D/audio_vloop: adev_set_mic_mute: 0
10-06 06:15:17.072 194-194/? D/audio_hw_primary: adev_set_parameters: enter: A2dpSuspended=false
10-06 06:15:17.072 194-194/? D/audio_vloop: adev_set_parameters(): [A2dpSuspended=false]
10-06 06:15:25.023 733-733/? W/AudioTrack: AUDIO_OUTPUT_FLAG_FAST denied by client; transfer 4, track 44100 Hz, output 48000 Hz
10-06 06:15:25.032 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:25.043 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
10-06 06:15:25.043 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker)
10-06 06:15:25.050 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback
10-06 06:15:26.431 1150-1298/? I/MicrophoneInputStream: mic_starting com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.443 194-1585/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:15:26.447 1150-1298/? I/MicrophoneInputStream: mic_started com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic)
10-06 06:15:26.457 194-1585/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:26.460 194-1585/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record
10-06 06:15:26.942 1150-1271/? I/AudioController: internalShutdown
10-06 06:15:26.943 1150-1271/? I/MicrophoneInputStream: mic_close com.google.android.apps.gsa.speech.audio.ag@c6eb0e1
10-06 06:15:26.943 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read
10-06 06:15:26.986 194-1585/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record
10-06 06:15:26.987 194-1585/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:27.066 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:27.100 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(7)
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback
10-06 06:15:30.257 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker)
10-06 06:15:30.262 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:30.272 194-607/? D/audio_hw_primary: select_devices: out_snd_device(2: speaker) in_snd_device(0: none)
10-06 06:15:30.273 194-607/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker)
10-06 06:15:30.280 194-607/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: low-latency-playback
10-06 06:15:30.347 194-607/? D/AudioFlinger: mixer(0xb4140000) throttle end: throttle time(10)
10-06 06:15:31.517 194-607/? D/audio_hw_primary: out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=2
10-06 06:15:31.751 1150-1298/? I/MicrophoneInputStream: mic_starting com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:31.762 194-1826/? I/AudioFlinger: AudioFlinger's thread 0xb3bc0000 ready to run
10-06 06:15:31.771 1150-1298/? I/MicrophoneInputStream: mic_started com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: select_devices: out_snd_device(0: none) in_snd_device(38: voice-rec-mic)
10-06 06:15:31.780 194-1826/? D/audio_hw_primary: enable_snd_device: snd_device(38: voice-rec-mic)
10-06 06:15:31.783 194-1826/? D/audio_hw_primary: enable_audio_route: apply and update mixer path: audio-record
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: low-latency-playback
10-06 06:15:34.695 194-607/? D/audio_hw_primary: disable_snd_device: snd_device(2: speaker)
10-06 06:15:34.850 1150-1271/? I/AudioController: internalShutdown
10-06 06:15:34.851 1150-1271/? I/MicrophoneInputStream: mic_close com.google.android.apps.gsa.speech.audio.ag@dd13203
10-06 06:15:34.851 1150-1298/? E/AudioRecord-JNI: Error -4 during AudioRecord native read
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_audio_route: reset and update mixer path: audio-record
10-06 06:15:34.885 194-1826/? D/audio_hw_primary: disable_snd_device: snd_device(38: voice-rec-mic)
我的是 audio_vloop。我可以看到 Android 打开我的设备,然后打开输入流,然后关闭输入流。它从不尝试打开输出流。 audio_vloop 实现了输入和输出流。此后,audio_vloop 中的任何内容都不会被 Android 调用。
我制作了一个播放音频的小应用程序(目前来自 pcm 文件)。我想将此输出重定向到我的 HAL。为了实现这一点,我相信我需要在我的音轨上做一个 AudioTrack.setPreferredDevice() 。我发现音频管理器应该有所有音频设备的列表。
所以我打电话给:
AudioDeviceInfo aDevInfo[] = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
它只找到 1 个设备,有关此设备的更多信息:
10-06 06:37:01.962 3295-3663/? D/AudioPlayer: Have [1] devices
10-06 06:37:01.964 3295-3663/? D/AudioPlayer: devInfo[0]: [Landroid.media.AudioDeviceInfo;@90bd9da
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getProductName()AOSP on Flo
10-06 06:37:01.965 3295-3663/? D/AudioPlayer: getType()2
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSink()true
10-06 06:37:01.966 3295-3663/? D/AudioPlayer: isSource()false
这貌似是我没有实现的audioPort。所以它不是来自我的 HAL。
在 Android 允许我的应用程序与我的设备对话之前,我显然错过了一个或多个步骤。
我需要能够将音频从我的应用程序发送到我的 HAL。 稍后,我还需要能够从我的 HAL 接收音频(通过 AudioRecord 等)。
在将我的 HAL 集成到 Android 中时我遗漏了什么? 我需要实现音频端口吗? 还需要其他东西吗?
更新 2
我发现 AOSP 中有错别字,在 AudioPolicyManager.cpp@2922
而不是 Output
,它打印 Input
我有这个日志 AudioPolicyManager: Input device 00020000 unreachable
,假设它在谈论 BT/A2DP 输入设备,我忽略了它。
我修复了我设备的日志,原来是我们要使用的线路输出设备。我现在正在调试这个方向
找到答案。
对于输出流:
- 不支持
AUDIO_CHANNEL_OUT_STEREO
的输出未被 Android 打开
提及标志
中的以下代码中很明显AUDIO_OUTPUT_FLAG_DIRECT
的输出不会被 Android 自动打开。这在AudioPolicyManager.cpp
if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { continue; }
来自 here
可能有一种以编程方式打开它们的方法,但我还没有找到答案。
这两个一旦修复就足以让 Android 开始使用我的输出流。
在流中:
流中已经是 AudioManager.getDevices()
因此可以在 AudioTrack.setPreferredDevice()
之后从流中的 vloop 中读取。
为了确保其他应用程序能够从 vloop 读取麦克风输入,我不得不声明它来实现 AUDIO_DEVICE_IN_BUILTIN_MIC
。为此,我还在 audio_policy.conf
.
AUDIO_DEVICE_IN_BUILTIN_MIC
此外,我在流立体声中制作只是为了保持与流缓冲区格式的兼容性。
经过这些改动,我看到vloop不断有读写调用。
更新:
我后来发现上述行为取决于音频策略管理器的实现。他们中的大多数行为相同,(例如,大多数打开 INBUILT_MIC 用于 VOICE_RECOGNITION 输入)但有些可能不是(Nexus Player)对于这些异常值,要么实施他们的 APM 打开的内容,要么修改 APM 以打开你的HAL 实现.