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 Parametertypaudio_source
erwartet und nicht der aktuell verwendeteAUDIO_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.