需要什么才能让Android使用新的音频HAL

需要什么才能让Android使用新的音频HAL

问题描述:

我正在编写新的Android音频HAL,让我的应用程序将音频馈送到其他应用程序,以允许我的手持式远程麦克风输入到达Google应用程序。本质上,一个虚拟音频电缆。需要什么才能让Android使用新的音频HAL

它的工作正在进行中。 我可能会压倒AUDIO_DEVICE_IN_BACK_MIC,但这是开放的建议。

我对如何确保Android使用此HAL进行输入存有疑问。

我需要替换audio.primary.default.so还是应该将其保留为audio.vcable.default.so?

更具体地说:如果我不更换主要的,Android如何知道使用我的HAL而不是主要?


更新:

我真的可以使用任何的帮助了这项工作。任何指针都很有帮助。

我已经写了一个音频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 [email protected] 
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 [email protected] 
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 [email protected] 
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 [email protected] 
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 [email protected] 
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 [email protected] 
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实现输入和输出流。在此之后,Android中不会调用audio_vloop中的任何内容。

我做了一个播放音频的小应用程序(现在是一个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一个错字,在[email protected]

相反的Output,它打印Input

我有这个日志AudioPolicyManager: Input device 00020000 unreachable我忽视假设它是谈论BT/A2DP输入设备。

我修复了我的设备的日志,事实证明我们想要使用Line out设备。我正在调试这个方向。

+1

您必须实现自己的[音频模块](https://android.googlesource.com/platform/hardware/libhardware/+/master/modules/usbaudio),并将其添加到“PRODUCT_PACKAGES”中你的设备makefile。您可能还必须将其添加到[AudioFlinger]中(https://android.googlesource.com/platform/frameworks/av/+/master/services/audioflinger/AudioFlinger.cpp#279)。可能还有其他需要改变的地方,这是我从事这类工作的一段时间。 – Michael

+0

另请参见[这是我的旧答案](http://*.com/questions/21024851/redirecting-audio-creating-alternate-sound-paths-in-android/21217919#21217919)我在哪里经历如何可以实现一个新的'AudioSource'来抓取某些Qualcomm平台上的当前音频输出。 – Michael

+0

does findSuitableHwDev_l()最终选择使用哪个音频hal?如果是的话,我可以修改它以始终选择我的模块进行音频输入。感谢指针。 – GPS

找到答案。

对于出流:不支持AUDIO_CHANNEL_OUT_STEREO

  1. 输出不被由Android
  2. 打开
  3. 输出提及标志AUDIO_OUTPUT_FLAG_DIRECT不是由Android自动打开。这是在下面的代码明显,在AudioPolicyManager.cpp

    if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { 
         continue; 
        } 
    

    here

有可能是在编程打开它们的一种方式,但我还没有找到答案。

这两个,一旦固定,足以让Android开始使用我的流。

对于流:

在流已经的AudioManager.getDevices()

结果的一部分,因此有可能从Vloop工作流AudioTrack.setPreferredDevice()后阅读。

要确保其他应用程序将读取vloop的麦克风输入,我必须声明它实现AUDIO_DEVICE_IN_BUILTIN_MIC。为了达到这个目的,我还从的主要HAL中删除了AUDIO_DEVICE_IN_BUILTIN_MIC

此外,我只是为了保持与流出缓冲区格式的兼容性而制作流式立体声。

经过这些更改后,我发现有连续的读写调用进入vloop。

UPDATE:

我后来发现,上述行为是依赖于音频策略管理器执行。它们中的大多数表现相同的方式(例如,大多数开放INBUILT_MIC VOICE_RECOGNITION输入)但有些可能不(Nexus Player)对于这些异常值,要么实现它们的APM打开什么,要么修改APM来打开你的HAL实现的东西。