Lo que se requiere para que Android utilice un nuevo Audio HAL
Estoy escribiendo un nuevo Android Audio HAL, para permitir que mi aplicación suministre audio a otras aplicaciones, para permitir que mi entrada de micrófono remoto de mano llegue a la aplicación de Google. Esencialmente, un cable de audio virtual.
Es un trabajo en progreso. Probablemente esté reemplazando a AUDIO_DEVICE_IN_BACK_MIC, pero esto está abierto para sugerencias.
- Volver a escribir el código Java a JS - la creación de un audio de bytes?
- Mezclador de canciones de audio en android mediante programación
- Android AudioRecord artefacto
- Cómo grabar audio desde un auricular bluetooth (startBluetoothSco ())
- Fregadero de Android 5.0 Bluetooth A2DP
Tengo dudas sobre cómo asegurarse de que Android utiliza este HAL para la entrada.
¿Necesito reemplazar audio.primary.default.so o debo dejarlo como audio.vcable.default.so?
Más específicamente: si no estoy reemplazando primaria, ¿cómo sabrá Android que usar mi HAL en lugar de primaria?
Actualizar:
Realmente podría usar cualquier ayuda en este trabajo. Cualquier puntero es útil.
He escrito un módulo Audio HAL. He añadido lo siguiente (elementos en negrita) a audio_policy.conf:
global:
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** }
Y bajo 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 } } }
También agregué el siguiente (negrita) a 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** };
Puedo ver que durante el arranque, mi HAL se carga, y obtener estos registros:
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)
El mío es audio_vloop. Puedo ver que Android abre mi dispositivo, luego abre el flujo de entrada y luego cierra el flujo de entrada. Nunca intenta abrir el flujo de salida. Audio_vloop implementa los flujos de entrada y salida. Después de esto, Android nunca invoca nada en audio_vloop.
Hice una pequeña aplicación que reproduce audio (desde un archivo pcm por ahora). Quiero redirigir esta salida a mi HAL. Para lograr esto, creo que necesito hacer un AudioTrack.setPreferredDevice () en mi pista de audio. He encontrado que el Administrador de audio debe tener una lista de todos los dispositivos de audio.
Así que llamo
AudioDeviceInfo aDevInfo[] = am.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
Sólo encuentra 1 dispositivo, más información en este dispositivo:
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
Esto aparentemente es de audioPort que no he implementado. Así que no es de mi HAL.
Obviamente, he perdido uno o más pasos antes de que Android permita que mi aplicación hable con mi dispositivo.
Necesito poder enviar audio de mi aplicación a mi HAL. Más tarde, también necesito ser capaz de recibir audio de mi HAL (a través de AudioRecord etc).
¿Qué extrañé al integrar mi HAL en Android? ¿Necesito implementar puertos de audio? ¿Se requiere algo más?
Actualización 2
He encontrado que hay un error tipográfico en AOSP, en AudioPolicyManager.cpp@2922
En lugar de Output
, imprime Input
Tenía este registro AudioPolicyManager: Input device 00020000 unreachable
que no AudioPolicyManager: Input device 00020000 unreachable
cuenta suponiendo que está hablando de dispositivo de entrada BT / A2DP.
Fijé el registro para mi dispositivo, y resulta ser el dispositivo de la Línea hacia fuera que queremos utilizar. Estoy depurando esta dirección ahora.
- Android - Función para encaminar audio entre el teléfono inteligente y el módulo bluetooth
- Decodificación de extracto de Android para codificar audio Mux
- Registrarse como reproductor de música y reproducir canciones
- Cómo sintetizar sonidos de piano en android / java
- Implementar sonidos en una aplicación Android
- Android Audio - Transmisión de generador de seno-tono comportamiento extraño
- Descodificación de archivos de audio y re-codificación al formato PCM deseado: 44,100 kHz, 2 canales, 16 bits
- Recuperar la carátula del álbum utilizando FFmpeg
Respuestas encontradas.
Para salir:
- Las aplicaciones que no admiten
AUDIO_CHANNEL_OUT_STEREO
no están siendo abiertas por Android -
Las salidas que mencionan la bandera
AUDIO_OUTPUT_FLAG_DIRECT
no son abiertas automáticamente por Android. Esto es evidente en el código siguiente enAudioPolicyManager.cpp
if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { continue; }
Desde aquí
Puede haber una manera de abrirlos en programatically, pero no he encontrado la respuesta a eso.
Estos dos, una vez fijos fueron suficientes para Android para empezar a utilizar mi salida.
Para en corriente:
En secuencia ya era una parte de los resultados de AudioManager.getDevices()
Así que fue posible leer de vloop en secuencia después de AudioTrack.setPreferredDevice()
.
Para asegurarme de que otras aplicaciones lean la entrada de micrófono de vloop, tuve que declararla para implementar AUDIO_DEVICE_IN_BUILTIN_MIC
. Para que esto funcione, también AUDIO_DEVICE_IN_BUILTIN_MIC
de HAL primaria en audio_policy.conf
.
Además, he hecho en estéreo de flujo sólo para mantener la compatibilidad con el formato de búfer de flujo de salida.
Después de estos cambios, veo que hay continuas llamadas de lectura y escritura que vienen a vloop.
ACTUALIZAR:
Posteriormente descubrí que el comportamiento mencionado anteriormente depende de la implementación del Administrador de Políticas de Audio. La mayoría de ellos se comportan de la misma manera (por ejemplo, la entrada más abierta de INBUILT_MIC para VOICE_RECOGNITION), pero algunos no pueden (Nexus Player) Para estos outliers, implemente lo que sus APM abran o modifique APM para abrir lo que implementa HAL.
- Añadiendo Admob a Libgdx juego
- ¿Hay alguna manera de detectar si un teléfono Android es compatible con la integración de Voicemail en el registro de llamadas?