Eingabegerät in AAOS verbinden

Sie können diese Mechanismen verwenden, um Audio in Android abzuspielen:

Jeder Mechanismus ermöglicht die Audiowiedergabe in Android. 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 aufzunehmen 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 stellt eine direkte Verbindung zwischen dem Audioquellgerät und einem Android-Mixer her.

Beweggründe

Bei der Verwendung eines Device-to-Device- oder Hardware-Audio-Patches mit Android können mehrere Einschränkungen auftreten. Bei jeder Option können keine Media-Tastenereignisse wie PLAY, PAUSE und STOP empfangen werden. Da sie den Audio-Stack von Android umgehen, ist für jede Option Hardware erforderlich, um den Patch in andere Audioinhalte von Android zu mischen.

HwAudioSource verwenden

HwAudioSource ist ein neuer Player, der als Softwarepatch konzipiert ist. Dadurch können Apps, die diesen Player verwenden, Media-Tastenereignisse empfangen und der Ausgabestream wird von Android gemischt und weitergeleitet.

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

Änderungen am Audio-HAL

Bei diesem neuen Player gelten die folgenden Erwartungen an den Audio-HAL. Beispiel: device/generic/car/emulator/audio/driver/audio_hw.c

  • adev_create_audio_patch erwartet, dass mit der Anfrage ein Audio-Patch von einem Gerät zu einem Mixer eingerichtet wird.

  • 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 Audio-Puffer mit Audiodaten aus dem Rundfunk.

Wir empfehlen, in audio_policy_configuration.xml ein Tunergerät mit dem Typ AUDIO_DEVICE_IN_FM_TUNER 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 mithilfe von AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS in Verbindung mit AudioDeviceInfo.TYPE_FM_TUNER leichter finden.

Audio-Patches erstellen

Sie können eine Audioverbindung zwischen zwei Audioanschlüssen herstellen, entweder einem Mix-Port oder einem Geräteanschluss. Normalerweise wird ein Audio-Patch vom Mix-Port zum Geräteport für die Wiedergabe verwendet, während die umgekehrte Richtung für die Aufnahme vorgesehen ist.

Beispielsweise umgeht ein Audio-Patch, der Audio-Samples von der Quelle FM_TUNER direkt an den Media-Sink weiterleitet, den Software-Mixer. Sie müssen dann einen Hardware-Mixer verwenden, um die Audio-Samples von Android und FM_TUNER für die Senke zu mischen. So erstellen Sie einen Audio-Patch direkt von der FM_TUNER-Quelle zum Media-Sink:

  • Die Lautstärkeregelung gilt für das Media-Sink und sollte sich sowohl auf Android- als auch auf FM_TUNER-Audio auswirken.

  • Nutzer können durch einfaches Wechseln der App zwischen Android- und FM_TUNER-Audio wechseln. Eine explizite Auswahl der Media-Quelle ist nicht erforderlich.

Bei Automotive-Implementierungen 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 den Geräteports zuordnen.

Beispielkonfiguration

device/generic/car/emulator/audio/audio_policy_configuration.xml ist eine Beispielkonfiguration.

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

Mit getExternalSources() können Sie eine Liste der verfügbaren Quellen (anhand der Adresse) abrufen und dann Audiopatches zwischen diesen Quellen und den Senkenports nach Audioverwendungen erstellen. Die entsprechenden Einstiegspunkte im Audio-HAL werden in IDevice.hal angezeigt:

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

Musik-Tuner

Wenn Sie eine Radio-App entwickeln, empfehlen wir die Verwendung von HwAudioSource, da damit sowohl das Erstellen des Patches als auch eine Mediensitzung zur Verarbeitung von Media-Key-Ereignissen erfolgt. Für dieselbe Quelle und dieselben Audioattribute können mehrere Audioquellen erstellt werden. Es ist möglich, einen für die normale Radionutzung und einen zweiten für Verkehrsmeldungen zu haben.

Wenn Sie den FM_TUNER aufzeichnen, wurde die Berechtigung dafür in Android 11 in android.permission.CAPTURE_AUDIO_OUTPUT geändert. Die Berechtigung OP_RECORD_AUDIO, die nur für Mikrofone gilt, wird nicht mehr überprüft. Das sollte keine Auswirkungen auf Apps haben, da für FM_TUNER bereits die Berechtigung SYSTEM_API für den Zugriff erforderlich ist.

Weitere Informationen zum Erstellen einer Radio-App finden Sie unter Radio implementieren.