2016-09-28 52 views
9

我正在編寫新的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://stackoverflow.com/questions/21024851/redirecting-audio-creating-alternate-sound-paths-in-android/21217919#21217919)我在哪裏經歷如何可以實現一個新的'AudioSource'來抓取某些Qualcomm平臺上的當前音頻輸出。 – Michael

+0

does findSuitableHwDev_l()最終選擇使用哪個音頻hal?如果是的話,我可以修改它以始終選擇我的模塊進行音頻輸入。感謝指針。 – GPS

回答

4

找到答案。

對於出流:不支持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實現的東西。

相關問題