Eingabegerät in AAOS verbinden

Sie können Audioinhalte auf Android-Geräten mit folgenden Mechanismen abspielen:

Mit jedem Mechanismus kann die Audiowiedergabe in Android erfolgen. Für die Radiowiedergabe oder die Wiedergabe von Eingabegeräten reichen diese Optionen möglicherweise nicht aus. Sie können jedoch mit der Audioaufnahme oder der Klasse MediaRecorder kombiniert werden, um zuerst das Audio zu erfassen und dann über Android wiederzugeben. Insbesondere für System-Apps können die folgenden Informationen verwendet werden, um ein Eingabegerät mit einem Ausgabemixer in AAOS zu verbinden.

HwAudioSource-Player

HwAudioSource verbindet das Audioquellengerät direkt mit einem Android-Mixer.

Motivationen

Bei der Verwendung eines Geräte-zu-Geräte- oder Hardware-Audio-Patches mit Android können mehrere Einschränkungen auftreten. Bei keiner der Optionen können wichtige Medienereignisse wie PLAY, PAUSE und STOP empfangen werden. Da sie den Audiostack von Android umgehen, ist für jede Option Hardware erforderlich, um den Patch in andere Audioinhalte von Android einzubinden.

HwAudioSource verwenden

HwAudioSource ist ein neuer Playertyp, der als Software-Patch konzipiert wurde. So können Apps, die diesen Player verwenden, Medienschlüsselereignisse empfangen und der Ausgabestream kann von Android gemischt und weitergeleitet werden.

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

Änderungen an der Audio-HAL

Beachten Sie bei diesem neuen Player die folgenden Anforderungen an die Audio-HAL. Beispiel: device/generic/car/emulator/audio/driver/audio_hw.c.

  • adev_create_audio_patch erwartet, dass die Anfrage einen Audio-Patch von einem Gerät zu einem Mixer herstellt.

  • Für adev_open_input_stream wird der Parametertyp audio_source erwartet und nicht der aktuell verwendete AUDIO_SOURCE_FM_TUNER.

  • in_read füllt den Audiopuffer mit Audiodaten von Radioübertragungen.

Wir empfehlen, ein Tunergerät vom Typ AUDIO_DEVICE_IN_FM_TUNER in audio_policy_configuration.xml so zu konfigurieren:

<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>

Mit dieser Gerätekonfiguration können Sie das FM-Radio-Eingabegerät leichter finden, indem Sie AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS in Kombination mit AudioDeviceInfo.TYPE_FM_TUNER verwenden.

Audio-Patches erstellen

Sie können einen Audio-Patch zwischen zwei Audioports erstellen, entweder einem Mix-Port oder einem Geräteport. Normalerweise dient ein Audio-Patch vom Mix-Port zum Geräteport der Wiedergabe, während die umgekehrte Richtung der Aufnahme dient.

Ein Audio-Patch, der Audio-Samples von der FM_TUNER-Quelle direkt an den Medien-Sink weiterleitet, umgeht beispielsweise den Software-Mixer. Sie müssen dann einen Hardware-Mixer verwenden, um die Audio-Samples von Android und FM_TUNER für den Sink zu mischen. So erstellst du einen Audio-Patch direkt von der FM_TUNER-Quelle zum Medien-Sink:

  • Die Lautstärkeregelung gilt für den Medien-Sink und sollte sich sowohl auf die Android- als auch auf die FM_TUNER-Audioausgabe auswirken.

  • Nutzer können über eine einfache App-Umschaltung zwischen Android- und FM_TUNER-Audio wechseln. Es ist keine explizite Auswahl der Medienquelle erforderlich.

Bei der Implementierung in der Automobilbranche muss möglicherweise auch ein Audio-Patch zwischen zwei Geräteports erstellt werden. Dazu müssen Sie zuerst die Geräteports und möglichen Routen in audio_policy_configuration.xml deklarieren und dann Mixports mit den Geräteports verknüpfen.

Beispielkonfiguration

Siehe diese Beispielkonfiguration, 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>

Audio Driver API

Mit getExternalSources() können Sie eine Liste der verfügbaren Quellen abrufen (anhand der Adresse), und dann Audio-Patches zwischen diesen Quellen und den Senkports nach Audionutzung erstellen. Die entsprechenden Eintragspunkte in der Audio-HAL sind in IDevice.hal zu finden:

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);
...
}

Radio-Tuner

Wenn du eine Radio-App entwickelst, empfehlen wir die Verwendung der HwAudioSource, da sie sowohl das Erstellen des Patches als auch eine Mediensitzung zum Verarbeiten von Medientastenereignissen übernimmt. Für dieselbe Quelle und dieselben Audioattribute können mehrere Audioquellen erstellt werden. Sie können einen für die normale Radionutzung und einen zweiten für Verkehrsmeldungen haben.

Bei der Aufzeichnung der FM_TUNER wurde die Berechtigung in Android 11 zu android.permission.CAPTURE_AUDIO_OUTPUT geändert. Die Berechtigungsprüfung für OP_RECORD_AUDIO, die nur für Mikrofone gilt, wird nicht mehr durchgeführt. Das sollte sich nicht auf Apps auswirken, da FM_TUNER bereits die Berechtigung SYSTEM_API für den Zugriff benötigt.

Weitere Informationen zum Erstellen einer Radio-App findest du unter Radio implementieren.