Alternativas a la creación de un jugador

Este artículo describe alternativas a la creación de un reproductor.

Reproductor HwAudioSource

HwAudioSource conecta el dispositivo fuente de audio directamente a un mezclador de Android.

Pueden surgir varias limitaciones al usar un parche de audio de dispositivo a dispositivo o de hardware con Android. Estos no pueden recibir eventos clave de medios como PLAY, PAUSE y STOP y, debido a que eluden la pila de audio de Android, requieren hardware para mezclar el parche con otro audio de Android.

Uso de HwAudioSource

HwAudioSource es un nuevo tipo de reproductor diseñado como un parche de software. Esto permite que Android mezcle y enrute las aplicaciones que usan este reproductor para recibir eventos clave de medios y el flujo de salida.

mHwAudioSource = new HwAudioSource.Builder()
                .setAudioDeviceInfo(AudioDeviceInfo: info)
                .setAudioAttributes(new AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_MEDIA)
                        .build())
                .build();
mHwAudioSource.play();
mHwAudioSource.stop();

Cambios en el audio HAL

Con este nuevo reproductor, hay un par de expectativas para el HAL de audio (por ejemplo, device/generic/car/emulator/audio/driver/audio_hw.c ):

  • adev_create_audio_patch espera que la solicitud establezca un parche de audio desde un dispositivo a un mezclador. Esto no requiere nada especial.
  • Adev_open_input_stream espera que la fuente de audio sea AUDIO_SOURCE_FM_TUNER
  • In_read llena el búfer de audio con datos de audio de radio de transmisión reales

Se recomienda configurar un dispositivo sintonizador con tipo AUDIO_DEVICE_IN_FM_TUNER en audio_policy_configuration.xml :

<devicePort
    tagName="Tuner_source"
    type="AUDIO_DEVICE_IN_FM_TUNER"
    role="source"
    address="tuner0">
    <profile
        name=""
        format="AUDIO_FORMAT_PCM_16_BIT"
        samplingRates="48000"
        channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</devicePort>

Con esta configuración de dispositivo, se puede facilitar la búsqueda del dispositivo de entrada de radio FM utilizando AudioManager.getDevices( AudioManager.GET_DEVICES_INPUTS ) junto con AudioDeviceInfo.TYPE_FM_TUNER .

Creación de parches de audio

Puede crear un parche de audio entre dos puertos de audio, ya sea un puerto de mezcla o un puerto de dispositivo. Por lo general, un parche de audio del puerto de mezcla al puerto del dispositivo es para reproducción, mientras que la dirección inversa es para captura.

Por ejemplo, un parche de audio que enruta muestras de audio desde la fuente FM_TUNER directamente al sumidero de medios pasa por alto el mezclador de software. Luego debe usar un mezclador de hardware para mezclar las muestras de audio de Android y FM_TUNER para el receptor. Al crear un parche de audio directamente desde la fuente FM_TUNER al sumidero de medios:

  • El control de volumen se aplica al disipador de medios y debería afectar tanto al audio de Android como al de FM_TUNER .
  • Los usuarios deberían poder cambiar entre el audio de Android y FM_TUNER a través de un simple cambio de aplicación (no debería ser necesaria una elección de fuente de medios explícita).

Las implementaciones automotrices también pueden necesitar crear un parche de audio entre dos puertos de dispositivo. Para hacerlo, primero debe declarar los puertos del dispositivo y las posibles rutas en audio_policy_configuration.xml y asociar mixports con estos puertos del dispositivo.

Ejemplo de configuración

Consulte también device/generic/car/emulator/audio/audio_policy_configuration.xml .

<audioPolicyConfiguration>
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_media_out</item>
                <item>bus1_audio_patch_test_in</item>
            </attachedDevices>
            <mixPorts>
                <mixPort name="mixport_bus0_media_out" role="source"
                        flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="mixport_audio_patch_in" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                           samplingRates="48000"
                           channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
                        address="bus0_media_out">
                    <profile balance="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
                <devicePort tagName="bus1_audio_patch_test_in" type="AUDIO_DEVICE_IN_BUS" role="source"
                        address="bus1_audio_patch_test_in">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out,bus1_audio_patch_test_in"/>
                <route type="mix" sink="mixport_audio_patch_in" sources="bus1_audio_patch_test_in"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>

API de controlador de audio

Puede usar getExternalSources() para recuperar una lista de fuentes disponibles (identificadas por dirección), luego crear parches de audio entre estas fuentes y los puertos receptores por usos de audio. Los puntos de entrada correspondientes en Audio HAL aparecen en IDevice.hal :

Interface IDevice {
...
/
* Creates an audio patch between several source and sink ports.  The handle
* is allocated by the HAL and must be unique for this audio HAL module.
*
* @param sources patch sources.
* @param sinks patch sinks.
* @return retval operation completion status.
* @return patch created patch handle.
*/
createAudioPatch(vec<AudioPortConfig> sources, vec<AudioPortConfig> sinks)
       generates (Result retval, AudioPatchHandle patch);

* Release an audio patch.
*
* @param patch patch handle.
* @return retval operation completion status.
*/
releaseAudioPatch(AudioPatchHandle patch) generates (Result retval);
...
}

Nota: estos ganchos de API han estado disponibles desde AUDIO_DEVICE_API_VERSION_3_0 . Para obtener más información, consulte device/generic/car/emulator/audio/driver/audio_hw.c .