Sie können diese Mechanismen verwenden, um Audio in Android abzuspielen:
Mit jedem Mechanismus kann die Audiowiedergabe in Android erfolgen. Für die Radio
wiedergabe oder die Wiedergabe von Eingabegeräten reichen diese Optionen möglicherweise nicht aus, sie können jedoch mit der Audioaufnahme oder der
MediaRecorder
Klasse kombiniert werden, um zuerst Audio aufzunehmen und es dann in 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 Audioquellgerät direkt mit einem Android-Mixer.
Motivation
Bei der Verwendung eines Audio-Patches von Gerät zu Gerät oder eines Hardware-Audio-Patches mit Android können mehrere Einschränkungen auftreten. Mit keiner der Optionen können 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-Typ, der als Software-Patch entwickelt wurde. So können Apps, die diesen Player verwenden, Media-Tastenereignisse 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
Bei diesem neuen Player müssen die folgenden Erwartungen an die Audio-HAL berücksichtigt werden. Beispiel: device/generic/car/emulator/audio/driver/audio_hw.c.
adev_create_audio_patcherwartet, dass die Anfrage einen Audio-Patch von einem Gerät zu einem Mixer einrichtet.adev_open_input_streamerwartet, dassaudio_sourceAUDIO_SOURCE_FM_TUNERist.in_readfüllt den Audio-Puffer mit Broadcast-Audiodaten.
Wir empfehlen, in audio_policy_configuration.xml ein Tuner-Gerä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 leichter finden, indem Sie AudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS in Verbindung mit AudioDeviceInfo.TYPE_FM_TUNER verwenden.
Audio-Patches erstellen
Sie können einen Audio-Patch zwischen zwei Audio-Ports erstellen, entweder einem Mix-Port oder einem Geräte-Port. In der Regel wird ein Audio-Patch vom Mix-Port zum Geräte-Port für die Wiedergabe verwendet, während die umgekehrte Richtung für die Aufnahme vorgesehen ist.
Ein Audio-Patch, der Audiosamples von der Quelle FM_TUNER direkt an die Media-Senke weiterleitet, umgeht beispielsweise den Software-Mixer. Sie müssen dann einen Hardware-Mixer verwenden, um die Audiosamples von Android und FM_TUNER für die Senke zu mischen. Beim Erstellen eines Audio-Patches direkt von der Quelle FM_TUNER zur Media-Senke gilt Folgendes:
Die Lautstärkeregelung gilt für die Media-Senke und sollte sich sowohl auf das Android- als auch auf das
FM_TUNER-Audio auswirken.Nutzer können durch einen einfachen App-Wechsel 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äte-Ports erstellt werden. Dazu müssen Sie zuerst die Geräte-Ports und möglichen Routen in audio_policy_configuration.xml deklarieren und dann Mix-Ports mit den Geräte-Ports verknüpfen.
Beispielkonfiguration
Sehen Sie sich diese Beispielkonfiguration an: 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-Treiber-API
Mit getExternalSources() können Sie eine Liste der verfügbaren Quellen (identifiziert durch die Adresse) abrufen und dann Audio-Patches zwischen diesen Quellen und den Senken-Ports nach Audio-Verwendungszwecken erstellen. Die entsprechenden Einstiegspunkte in der Audio-HAL finden Sie in 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);
...
}
Radio tuner
Wenn Sie eine Radio-App entwickeln, empfehlen wir die Verwendung von HwAudioSource, da damit sowohl der Patch als auch eine Media-Sitzung zum Verarbeiten von Media-Tastenereignissen erstellt werden. Für dieselbe Quelle und dieselben Audioattribute können mehrere Audioquellen erstellt werden. Es ist möglich, eine für die normale Radionutzung und eine zweite für Verkehrsmeldungen zu verwenden.
Wenn Sie den FM_TUNER aufnehmen, wurde die Berechtigung dafür in Android 11 in android.permission.CAPTURE_AUDIO_OUTPUT geändert.
Die Berechtigungsprüfung OP_RECORD_AUDIO, die nur für Mikrofone gilt, wird nicht mehr durchgeführt. Dies sollte sich nicht auf Apps auswirken, da für den Zugriff auf FM_TUNER bereits die Berechtigung SYSTEM_API erforderlich ist.
Weitere Informationen zum Erstellen einer Radio-App finden Sie unter Radio implementieren.