2016-09-28 1 views
9

저는 내 앱이 다른 앱에 오디오를 공급하여 내 핸드 헬드 원격 마이크 입력이 Google 앱에 도달 할 수 있도록하기 위해 새로운 Android Audio HAL을 쓰고 있습니다. 본질적으로, 가상 오디오 케이블.Android에서 새로운 오디오를 사용하는 데 필요한 것

진행 중입니다. 아마 AUDIO_DEVICE_IN_BACK_MIC을 (를) 재정의 할 예정이지만 제안 사항은 없습니다.

안드로이드가이 HAL을 입력에 사용하는지 확인하는 방법에 의문을 가지고 있습니다.

audio.primary.default.so를 교체해야하나요, 아니면 audio.vcable.default.so로 두어야합니까?

보다 구체적으로 : 내가 1 차를 대체하지 않는다면 안드로이드가 1 차 대신 내 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()를 오디오 트랙에서 수행해야한다고 생각합니다. Audio Manager에 모든 오디오 장치 목록이 있어야합니다.

은 그래서 전화 : 이것은 겉으로는 내가 구현하지 않은 오디오 포트에서입니다

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 

: 그것은 단지 1 개 장치,이 장치에 대한 추가 정보를 찾아

AudioDeviceInfo aDevInfo[] = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS); 

. 그래서 그것은 나의 HAL 출신이 아닙니다.

안드로이드가 내 앱과 내 기기를 이야기하기 전에 분명히 하나 이상의 단계를 빠뜨렸습니다.

내 앱에서 내 HAL로 오디오를 전송할 수 있어야합니다. 나중에 (AudioRecord 등을 통해) HAL에서 오디오를 수신 할 수 있어야합니다.

HAL을 Android에 통합하는 데있어서 무엇을 놓쳤습니까? 오디오 포트를 구현해야합니까? 다른 것이 필요합니까?


업데이트 2

내가 [email protected]

대신 Output에, AOSP에 오타가 발견, 그것이 내가이 로그 AudioPolicyManager: Input device 00020000 unreachable했다 Input

를 인쇄하는 나는 그것이 가정 무시 BT/A2DP 입력 장치에 대해 이야기합니다.

내 장치에 대한 로그를 수정했는데 사용하려는 라인 출력 장치로 판명되었습니다. 지금이 방향을 디버깅 중입니다.

+1

자신 만의 [오디오 모듈] (https://android.googlesource.com/platform/hardware/libhardware/+/master/modules/usbaudio)을 구현하고에있는 'PRODUCT_PACKAGES'에 추가해야합니다. 귀하의 장치 메이크 파일. 아마 '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)도 참조하십시오. 일부 Qualcomm 플랫폼에서 현재 오디오 출력을 가져 오는 새로운 'AudioSource'를 구현하십시오. – Michael

+0

findSuitableHwDev_l()은 궁극적으로 사용할 오디오 hal을 선택합니까? 그렇다면 오디오 입력을 위해 항상 내 모듈을 선택하도록 수정할 수 있습니다. 포인터 주셔서 감사. – GPS

답변

4

발견 된 답변. 출력 스트림

:AUDIO_CHANNEL_OUT_STEREO를 지원하지 않는

  1. 출력은 플래그 AUDIO_OUTPUT_FLAG_DIRECT을 언급
  2. 출력이 자동으로 안드로이드가 열리지 않습니다 안드로이드

  3. 열되지 않습니다. 이 프로그래밍 방식에서 열 수있는 방법이있을 수 있습니다 here

에서 AudioPolicyManager.cpp

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

에 다음 코드에 분명하다,하지만 난 그에게 답을 발견하지 않았습니다.

이 두 개는 Android가 내 스트림을 사용하기에 충분하도록 고쳐졌습니다. 스트림 용

:

기류는 그래서 AudioTrack.setPreferredDevice() 후 vloop 스트림으로부터 판독 할 수 있었다 이미 AudioManager.getDevices()

결과의 일부이다.

다른 응용 프로그램이 vloop의 마이크 입력을 읽도록하려면 AUDIO_DEVICE_IN_BUILTIN_MIC을 구현하도록 선언해야했습니다. 이를 위해 audio_policy.conf의 기본 HAL에서 AUDIO_DEVICE_IN_BUILTIN_MIC을 삭제했습니다.

또한 스트림 스트림 형식으로 만 호환되도록 스트림 스테레오를 만들었습니다.

이 변경 후 vloop에 계속해서 읽기 및 쓰기 호출이 있음을 알 수 있습니다.

UPDATE :

나중에 위에서 언급 한 행동이 오디오 정책 관리자 구현에 의존하는 것으로 나타났다. 대부분은 같은 방식으로 작동합니다 (예 :VOICE_RECOGNITION 입력에 대해서는 INBUILT_MIC이 가장 많이 열려 있지만 일부는 그렇지 않을 수 있습니다. (Nexus Player) 이러한 이상치의 경우 APM이 실행하는 것을 구현하거나 APM을 수정하여 HAL 구현을 엽니 다.

관련 문제