voz vez usar salidas salida parlante google frontal configurar como comandos celular auriculares altavoz activar android audio alsa opensl

vez - Redirigir audio/crear rutas de sonido alternativas en Android



dos salidas de audio a la vez android (1)

¿Alguien tiene experiencia (usando OpenSL ES, ALSA, etc.) con la redirección de audio o la creación de nuevas rutas de sonido en Android? El objetivo final es crear un micrófono virtual para reemplazar el micrófono externo, donde uno puede reproducir archivos de audio como si estuvieran hablando por el micrófono. Las aplicaciones que accedan al micrófono con AudioSource.MIC deben usar esta secuencia alternativa. No es necesario que funcione con llamadas de voz, creo que lograr ese tipo de funcionalidad es más difícil ya que todo se hace dentro de la radio.

¿Alguna idea de por dónde empezar? Hice algunas investigaciones con OpenSL y ALSA, pero parece que tendré que empaquetar un nuevo firmware (ROM) para definir rutas de audio personalizadas. Si se puede evitar, me gustaría crear una solución a nivel de aplicación. Los teléfonos están "rooteados" (tienen sus binarios). El dispositivo de destino para esto es el Samsung Galaxy S4 Edición de Google (GT-i9505G). Específicamente, estoy buscando configuraciones de controladores de audio / código fuente o cualquier referencia para el i9505G.

¡Gracias por adelantado!

editar - He comprobado el árbol fuente de CyanogenMod 10.2, junto con los controladores jfltexx y kernel. Aquí están los contenidos de kernel / samsung / jf / sound: http://pastebin.com/7vK8THcZ . ¿Está esto documentado en algún lugar?


Una vez implementé la funcionalidad que buscas en un teléfono basado en la plataforma APQ8064 de Qualcomm (que parece ser casi la misma plataforma que la de tu dispositivo de destino). A continuación hay un resumen de lo que puedo recordar de esto, ya que no tengo acceso al código que escribí, o un entorno en el que puedo hacer fácilmente este tipo de modificaciones. Entonces, si esta respuesta parece un desastre de recuerdos fragmentarios, es porque eso es exactamente lo que es.

Esta información también puede aplicarse más o menos a otras plataformas de Qualcomm (como MSM8960 o MSM8974), pero es muy probable que sea completamente inútil para plataformas de otros proveedores (NVidia Tegra, Samsung Exynos, TI OMAP, etc.).

Una breve nota: el método que utilicé significa que el audio que obtiene la aplicación de grabación habrá pasado por el control de mezcla / volumen en el marco multimedia Android y / o el DSP multimedia de la plataforma. Por lo tanto, si está reproduciendo algo al 75% del volumen, lo graba y luego reproduce la grabación al 75% del volumen, puede que termine sonando bastante tranquilo. Si desea obtener datos PCM no procesados ​​(después de la decodificación, pero antes del control de mezcla / volumen), tendrá que buscar otro enfoque, por ejemplo, personalizar AudioFlinger , pero eso no es algo que haya intentado o que pueda proporcionar información.

Algunas ubicaciones de interés:

Los controladores de audio de la plataforma . Particularmente el archivo msm-pcm-routing.c .

El archivo de configuración de ALSA UCM (Administrador de casos de uso) . Este es solo un ejemplo de archivo de configuración UCM. Hay muchas variantes de estos archivos en función de la plataforma exacta utilizada, por lo que puede tener un nombre ligeramente diferente (aunque debería comenzar con snd_soc_msm_ ), y su contenido también diferirá ligeramente del que he vinculado.
NOTA para Kitkat y posterior: los archivos de configuración de UCM se usaron en Jellybean (y posiblemente en ICS). mixer_paths.xml entiendo, estas configuraciones se han movido a un archivo llamado mixer_paths.xml en Kitkat. Los contenidos son prácticamente iguales, solo en un formato diferente.

El código de audio HAL . ALSA UCM está presente en libalsa-intf , y el AudioHardware / AudioPolicyManager / ALSADevice está presente en audio-alsa . Tenga en cuenta que este código es para Jellybean, ya que esa es la última versión con la que estoy familiarizado. La estructura del directorio (y posiblemente algunos de los archivos / clases) difiere en Kitkat.

Si abre el archivo de configuración de UCM y busca "HiFiPROXY Rx" , encontrará algo como esto:

SectionVerb Name "HiFiPROXY Rx" EnableSequence ''AFE_PCM_RX Audio Mixer MultiMedia1'':1:1 EndSequence DisableSequence ''AFE_PCM_RX Audio Mixer MultiMedia1'':1:0 EndSequence # ALSA PCMs CapturePCM 0 PlaybackPCM 0 EndSection

Esto define un verbo (esencialmente la base de un caso de uso de audio, también hay modificadores que se pueden aplicar sobre los verbos para cosas como la reproducción simultánea y la grabación) con el nombre "HiFiPROXY Rx" (el apodo HiFi se usa para la mayoría verbos que no son de voz, PROXY refiere al dispositivo de audio utilizado, y Rx significa salida) y especifica a qué control ALSA escribir y qué escribirles cuando el caso de uso debe habilitarse / deshabilitarse. Finalmente, enumera los dispositivos de reproducción / captura PCM de ALSA para usar en este caso de uso. Por ejemplo, PlaybackPCM 0 significa que se debe usar el dispositivo de reproducción 0 (se supone que la tarjeta ALSA es la que representa el códec de hardware incorporado, que normalmente es la tarjeta 0). Estos verbos son seleccionados por el HAL de audio en función del caso de uso (reproducción de música, llamada de voz, grabación, ...), qué accesorios tiene adjuntos, etc.

Si busca "AFE_PCM_RX Audio Mixer" en la tabla msm_qdsp6_widgets en msm-pcm-routing.c , verá que se refiere a una lista de controles de mezclador llamada afe_pcm_rx_mixer_controls que se ve así:

static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_AFE_PCM_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_AFE_PCM_RX, ... and so on...

Esto enumera los DAI frontales que puede conectar al DAI de fondo ( AFE_PCM_RX ). Para tener una idea de cómo se relacionan entre sí, vea estos diagramas .
AFE_PCM_RX y AFE_PCM_TX son un par de DAI en algunas plataformas de Qualcomm que implementan una especie de dispositivo ficticio / proxy. Lo que hace es alimentar audio en AFE_PCM_RX que luego es procesado por el DSP multimedia (QDSP), y luego puede leerlo a través de AFE_PCM_TX . Esto se usa para implementar el enrutamiento de audio USB y WiFi, y también A2DP IIRC.

Volver a la línea AFE_PCM_RX Audio Mixer MultiMedia1 : dice que está alimentando MultiMedia1 en el AFE_PCM_RX Audio Mixer . MultiMedia1 se utiliza para la reproducción / grabación normal, y corresponde a pcmC0D0 (debe poder enumerar los dispositivos en su teléfono con adb shell cat /proc/asound/devices ). Hay otros DAI frontales, como MultiMedia3 y MultiMedia5 que se utilizan en casos especiales, como la reproducción de baja latencia y la reproducción de audio de baja potencia.
Al alimentar MultiMedia1 al AFE_PCM_RX Audio Mixer todo lo que escriba en el dispositivo de reproducción 0 en la tarjeta 0 será alimentado al AFE_PCM_RX . Para leerlo, podría configurar un verbo UCM que haga algo como ''MultiMedia1 Mixer AFE_PCM_TX'':1:1 , y luego leería desde pcmC0D0c (que debería ser el dispositivo de captura ALSA predeterminado).

Una prueba simple sería extraer el archivo de configuración de UCM de su teléfono (debería ubicarse en algún lugar debajo de /system/etc/ ) y modificar la "HiFi" EnableSequence del verbo "HiFi" con algo como:

''AFE_PCM_RX Audio Mixer MultiMedia1'':1:1 ''AFE_PCM_RX Audio Mixer MultiMedia3'':1:1 ''AFE_PCM_RX Audio Mixer MultiMedia5'':1:1

(y de manera similar en DisableSequence , pero con :1:0 al final de cada línea).

Luego vaya al modificador "Capture Music" (este es el modificador mal nombrado para la grabación normal) y cambie SLIM_0_TX a AFE_PCM_TX .

Copie el archivo de configuración de UCM modificado de nuevo al teléfono (requiere permiso de root) y reinicie el teléfono. A continuación, inicie la reproducción (conecte un auricular con cable / auriculares, deshabilite los sonidos táctiles para que el verbo de baja latencia no sea seleccionado) y comience una grabación desde AudioSource.MIC . Luego, verifique la grabación y vea si pudo grabar el audio de reproducción. Si no, entonces tal vez se seleccionó el verbo de audio de baja potencia y tendrá que modificar el verbo "HiFi Low Power" forma similar a lo que hizo con el verbo "HiFi" . Te ayudará si tienes habilitadas todas las impresiones de depuración en la HAL de audio (es decir, el comentario #define LOG_NDEBUG 0 en todos los archivos cpp donde puedes encontrarlo) para que puedas ver qué verbos / modificadores de UCM se seleccionan.

La modificación que describí anteriormente se vuelve un poco tediosa ya que tiene que cubrir todos los DAI front-end de MultiMedia para todos los verbos y modificadores relevantes.
IIRC, pude simplificar esto en solo una línea por verbo / modificador:

''AFE_PCM_RX Port Mixer SLIM_0_RX'':1:1

Si miras los verbos "HiFi ", "HiFi Low Power ", "HiFi Lowlatency" verás que todos usan SLIMBUS_0_RX back-end DAI, así que estoy aprovechando eso usando el AFE_PCM_RX Port Mixer que permite configuré una conexión desde un DAI de back-end a otro DAI de back-end. Si afe_pcm_rx_port_mixer_controls los afe_pcm_rx_port_mixer_controls y intercon en msm-pcm-routing.c , notarás que no hay entrada AFE_PCM_RX Port Mixer para AFE_PCM_RX Port Mixer , así que tendrías que agregarlos tú mismo (es solo una cuestión de copiar y pegar algunos de las líneas existentes y cambiando los nombres).

Algunos de los otros cambios que probablemente deba hacer:

  • En frameworks / base y frameworks / av (por ejemplo, AudioManager , AudioService , AudioSystem ), debe agregar una nueva constante AudioSource y asegurarse de que se reconozca en todos los lugares necesarios.

  • En el archivo de configuración de UCM, deberá agregar algunos verbos / modificadores nuevos para configurar correctamente los controles ALSA cuando se use su nuevo AudioSource .

  • En el HAL de audio tendría que hacer algunos cambios para que sus nuevos verbos / modificadores sean seleccionados cuando se use su nuevo AudioSource . Tenga en cuenta que hay una clase base de AudioPolicyManagerALSA llamada AudioPolicyManagerBase que también podría tener que modificar (está ubicada en otra parte del árbol de fuentes ).