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.