WARNUNG: OpenSL ES wird eingestellt. Entwickler sollten die Open-Source- Oboenbibliothek, die auf GitHub verfügbar ist Oboe ist ein C++-Wrapper, der eine API bietet, die AAudio sehr ähnelt. Oboe ruft AAudio auf, wenn AAudio verfügbar ist, und wechselt zu OpenSL ES, wenn AAudio nicht verfügbar ist.
OpenSL ES for Android erweitert die OpenSL ES-Referenzspezifikation, um sie mit Android kompatibel zu machen und die Leistung und Flexibilität der Android-Plattform zu nutzen.
Die Definition der API für die Android-Erweiterungen findest du unter OpenSLES_Android.h
und die darin enthaltenen Header-Dateien. Wende dich an OpenSLES_Android.h
finden Sie weitere Informationen zu diesen Erweiterungen. Sie befindet sich im Stammverzeichnis der Installation im Verzeichnis sysroot/usr/include/SLES
. Sofern nicht anders angegeben, sind alle Schnittstellen explizit.
Diese Erweiterungen beschränken die Portabilität Ihrer Anwendung auf
andere OpenSL ES-Implementierungen, da diese Android-spezifisch sind. Sie können dieses Problem beheben,
Vermeidung der Verwendung der Erweiterungen oder Verwendung von #ifdef
, um sie bei der Kompilierung auszuschließen.
In der folgenden Tabelle sind die Android-spezifischen Schnittstellen und Datenlocator aufgeführt, die Android OpenSL ES für jeden Objekttyp unterstützt. Die Werte Ja in den Zellen geben die Schnittstellen und Datenlocator an, die für jeden Objekttyp verfügbar sind.
Funktion | Audio player | Audiorekorder | Motor | Ausgabemix |
---|---|---|---|---|
Android-Pufferwarteschlange | Ja: Quelle (decodieren) | Nein | Nein | Nein |
Android-Konfiguration | Ja | Ja | Nein | Nein |
Android-Effekt | Ja | Nein | Nein | Ja |
Effektfunktionen für Android | Nein | Nein | Ja | Nein |
Android-Effekt senden | Ja | Nein | Nein | Nein |
Einfache Android-Zwischenspeicherwarteschlange | Ja: Quelle (Wiedergabe) oder Senke (Decodierung) | Ja | Nein | Nein |
Daten-Locator für Android-Pufferwarteschlange | Ja: Quelle (decodieren) | Nein | Nein | Nein |
Datensuche für Android-Dateideskriptoren | Ja: Quelle | Nein | Nein | Nein |
Einfache Android-Zwischenspeicherwarteschlange | Ja: Quelle (Wiedergabe) oder Senke (Dekodierung) | Ja: Senke | Nein | Nein |
Android-Konfigurationsoberfläche
Über die Android-Konfigurationsoberfläche können Sie plattformspezifische Parameter für Objekte festlegen. Diese Schnittstelle unterscheidet sich von anderen OpenSL ES
1.0.1-Schnittstellen, da Ihre App sie verwenden kann, bevor das entsprechende Objekt instanziiert wird; Somit gilt:
können Sie das Objekt konfigurieren,
bevor Sie es instanziieren. Die
OpenSLES_AndroidConfiguration.h
-Headerdatei, die sich hier befindet:
/sysroot/usr/include/SLES
,
dokumentiert die folgenden verfügbaren Konfigurationsschlüssel und -werte:
- Streamtyp für Audioplayer (Standardeinstellung:
SL_ANDROID_STREAM_MEDIA
). - Profil für Audiorekorder aufnehmen (Standardeinstellung:
SL_ANDROID_RECORDING_PRESET_GENERIC
).
Das folgende Code-Snippet zeigt ein Beispiel dafür, wie Sie den Android-Audiostreamtyp auf einem Audioplayer festlegen:
// CreateAudioPlayer and specify SL_IID_ANDROIDCONFIGURATION // in the required interface ID array. Do not realize player yet. // ... SLAndroidConfigurationItf playerConfig; result = (*playerObject)->GetInterface(playerObject, SL_IID_ANDROIDCONFIGURATION, &playerConfig); assert(SL_RESULT_SUCCESS == result); SLint32 streamType = SL_ANDROID_STREAM_ALARM; result = (*playerConfig)->SetConfiguration(playerConfig, SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32)); assert(SL_RESULT_SUCCESS == result); // ... // Now realize the player here.
Mit ähnlichem Code können Sie die Voreinstellung für einen Audiorekorder konfigurieren:
// ... obtain the configuration interface as the first four lines above, then: SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; result = (*playerConfig)->SetConfiguration(playerConfig, RECORDING_PRESET, &presetValue, sizeof(SLuint32));
Android-Effekte
Die Oberflächen für Effekt, Effektversand und Effektfunktion von Android bieten Ein generischer Mechanismus, mit dem eine Anwendung gerätespezifische Abfragen abruft und verwendet Audioeffekte. Gerätehersteller sollten alle verfügbaren gerätespezifischen Audioeffekte dokumentieren die sie bieten.
Mobile Anwendungen sollten für Audioeffekte die OpenSL ES 1.0.1 APIs anstelle der Android-API verwenden. Effekterweiterungen.
Android-Dateideskriptor-Daten-Locator
Mit dem Android File Deskriptor Data Locator können Sie die Quelle einer Audioplayer als offene Dateibeschreibung mit Lesezugriff. Das Datenformat muss MIME sein.
Diese Erweiterung ist besonders nützlich in Verbindung mit dem nativen Asset-Manager, da die App Assets über einen Dateideskriptor aus dem APK liest.
Android-Datensucher und -schnittstelle für einfache Pufferwarteschlangen
In der Referenzspezifikation von OpenSL ES 1.0.1 können Pufferwarteschlangen nur für Audioplayer verwendet werden. Sie sind kompatibel mit PCM und anderen Datenformaten. Die Datenlocator- und Schnittstellenspezifikationen der einfachen Android-Pufferwarteschlange sind mit zwei Ausnahmen mit der Referenzspezifikation identisch:
- Sie können einfache Android-Pufferwarteschlangen mit Audiorekordern und Audioplayern verwenden.
- Sie können das PCM-Datenformat nur mit diesen Warteschlangen verwenden.
Für die Aufzeichnung sollte Ihre App leere Puffer anstellen. Wenn ein registrierter Rückruf dass das System die Daten in einen Zwischenspeicher geschrieben hat, kann die App aus diesem Zwischenspeicher gelesen werden.
Die Wiedergabe funktioniert auf die gleiche Weise. Für zukünftigen Quellcode Kompatibilität. Wir empfehlen jedoch, für Apps die einfache Android-Version anstelle von OpenSL ES 1.0.1-Pufferwarteschlangen.
Verhalten der Pufferwarteschlange
Die Android-Implementierung entspricht nicht der Anforderung der Referenzspezifikation, dass der Wiedergabecursor zum Anfang des aktuell wiedergegebenen Buffers zurückkehren muss, wenn die Wiedergabe den Status SL_PLAYSTATE_STOPPED
erreicht. Diese Implementierung kann diesem Verhalten entsprechen oder den Ort der Wiedergabe beibehalten.
Cursor unverändert.
Daher kann Ihre App nicht davon ausgehen, dass eines der beiden Verhaltensweisen auftritt. Daher sollten Sie die BufferQueue::Clear()
-Methode nach einem Übergang zu SL_PLAYSTATE_STOPPED
explizit aufrufen. Dadurch wird die Pufferwarteschlange auf einen bekannten Status gesetzt.
Ebenso gibt es keine Spezifikation, die festlegt, ob der Auslöser für einen Pufferwarteschlangen-Rückruf notwendig ist.
ein Übergang zu SL_PLAYSTATE_STOPPED
oder eine Ausführung von
BufferQueue::Clear()
. Wir empfehlen daher, keine Abhängigkeit von einer der beiden Versionen zu erstellen. Stattdessen sollte Ihre App beide unterstützen.
Dynamische Benutzeroberflächen bei der Objekterstellung
Zur Vereinfachung ermöglicht die Android-Implementierung von OpenSL ES 1.0.1 Ihrer App, dynamische Schnittstellen anzugeben, wenn sie ein Objekt instanziiert.
Das ist eine Alternative zur Verwendung von DynamicInterfaceManagement::AddInterface()
, um diese Schnittstellen nach der Instanziierung hinzuzufügen.
Berichte zu Erweiterungen
Es gibt drei Methoden, um abzufragen, ob die Plattform Android-Erweiterungen unterstützt. Diese Methoden sind:
Engine::QueryNumSupportedExtensions()
Engine::QuerySupportedExtension()
Engine::IsExtensionSupported()
Jede dieser Methoden gibt ANDROID_SDK_LEVEL_<API-level>
zurück.
Dabei ist API-level
die API-Ebene der Plattform. z. B. ANDROID_SDK_LEVEL_23
.
Ein Plattform-API-Level von 9 oder höher bedeutet, dass die Plattform die Erweiterungen unterstützt.
Audio in PCM decodieren
In diesem Abschnitt wird eine eingestellte Android-spezifische Erweiterung für OpenSL ES 1.0.1 beschrieben. zum Decodieren eines codierten Streams in PCM ohne sofortige Wiedergabe. In der folgenden Tabelle finden Sie Empfehlungen für die Verwendung dieser Erweiterung und Alternativen.
API-Ebene | Alternativen |
---|---|
Unter 15 Jahre | Ein Open-Source-Codec mit einer geeigneten Lizenz |
16 bis 20 |
Die Klasse MediaCodec oder ein Open-Source-Codec mit einer entsprechenden Lizenz
|
21 oder älter |
NDK MediaCodec in den <media/NdkMedia*.h> -Headerdateien, der
MediaCodec -Klasse oder einen Open-Source-Codec mit einer entsprechenden Lizenz
|
Hinweis: Derzeit gibt es keine Dokumentation für die NDK-Version der MediaCodec
API. Sie können jedoch
finden Sie in den
nativen Codec.
Ein Standard-Audioplayer gibt die Wiedergabe auf einem Audiogerät wieder und gibt den Ausgabemix als Datensenke an. Die Android-Erweiterung unterscheidet sich dadurch, dass ein Audioplayer agiert als Decodierer, wenn die App die Datenquelle entweder als URI oder als Android- Data Locator für Dateideskriptoren, der mit dem MIME-Datenformat beschrieben wird. In diesem Fall ist die Datensenke eine einfache Android-Zwischenspeicherwarteschlange in Data Locator, die das PCM-Datenformat verwendet.
Diese Funktion ist in erster Linie für Spiele gedacht, bei denen Audio-Assets vorab geladen werden, wenn zu einem
neuen Spiel-Level, das den Funktionen ähnelt, die SoundPool
der Klasse bietet.
Die Anwendung sollte zunächst eine Reihe von leeren Puffern in die einfache Android-App Pufferwarteschlange. Anschließend füllt die App die Zwischenspeicher mit PCM-Daten. Der Android-Callback für die einfache Pufferwarteschlange wird nach jedem gefüllten Puffer ausgelöst. Der Callback-Handler verarbeitet die PCM-Daten, stellt den jetzt leeren Zwischenspeicher noch einmal in die Warteschlange und kehrt dann zurück. Die Anwendung ist verantwortlich für die Verfolgung decodierter Puffer, enthält die Liste der Callback-Parameter keine genügend Informationen vorhanden sind, um den Zwischenspeicher anzugeben, der die Daten enthält, oder den Zwischenspeicher, der aktualisiert werden soll. in die Warteschlange.
Die Datenquelle meldet das Ende des Streams implizit, indem sie am Ende des Streams ein SL_PLAYEVENT_HEADATEND
-Ereignis sendet. Nachdem die App alle empfangenen Daten decodiert hat, werden keine weiteren Aufrufe an den Callback der einfachen Android-Pufferwarteschlange ausgeführt.
Das PCM-Datenformat der Senke entspricht in der Regel dem der codierten Datenquelle in Bezug auf Abtastrate, Kanalanzahl und Bittiefe. Sie können jedoch in einen anderen Abtastrate, Kanalanzahl oder Bittiefe. Informationen zu einer Vorkehrung zum Erkennen des tatsächlichen PCM-Formats findest du unter Format von decodierten PCM-Daten über Metadaten ermitteln.
Die PCM-Decodierungsfunktion von OpenSL ES für Android unterstützt das Pausieren und die anfängliche Suche. es wird nicht unterstützt Lautstärkeregelung, Effekte, Schleifen oder Wiedergabegeschwindigkeit.
Je nach Plattformimplementierung sind für die Dekodierung möglicherweise Ressourcen erforderlich, die nicht inaktiv sein dürfen. Daher empfehlen wir Ihnen, eine ausreichende Anzahl von leeren PCM-Zwischenspeichern; sonst verhungert der Decoder. Das kann passieren, Wenn Ihre App beispielsweise vom Rückruf der einfachen Android-Zwischenspeicherwarteschlange ohne und einen leeren Puffer in die Warteschlange einreiht. Das Ergebnis eines Decodermangels nicht spezifiziert, kann jedoch Folgendes beinhalten: Löschen der decodierten PCM-Daten, Unterbrechung des Decodierungsvorgangs oder vollständiges Beenden des Decoders.
Hinweis: Wenn Sie einen codierten Stream in PCM decodieren, aber nicht sofort wiedergeben möchten, empfehlen wir für Apps, die auf Android 4.x (API-Ebenen 16–20) ausgeführt werden, die Klasse MediaCodec
.
Für neue Apps mit Android 5.0 (API-Level 21) oder höher empfehlen wir die Verwendung des NDK
Äquivalent, <NdkMedia*.h>
. Diese Headerdateien befinden sich im Verzeichnis media/
im Stammverzeichnis der Installation.
Streaming von ADTS AAC zu PCM decodieren
Ein Audioplayer fungiert als Streaming-Decodierer, wenn die Datenquelle ein Datensuche für die Android-Zwischenspeicherwarteschlange, die das MIME-Datenformat verwendet, und die Daten sink ist ein einfacher Android-Zwischenspeicher für Zwischenspeicherwarteschlangen, der das PCM-Datenformat verwendet. Konfigurieren Sie das MIME-Datenformat so:
- Container:
SL_CONTAINERTYPE_RAW
- MIME-Typ-String:
SL_ANDROID_MIME_AACADTS
Diese Funktion ist in erster Linie für Streaming-Media-Anwendungen gedacht, arbeiten mit AAC-Audio, müssen aber eine eigene Audioverarbeitung durchführen. vor der Wiedergabe. Die meisten Anwendungen, die Audio in PCM decodieren müssen sollten Sie die unter Audio in PCM decodieren beschriebene Methode verwenden. da diese Methode einfacher ist und mehr Audioformate verarbeiten kann. Die beschriebene Technik ist hier ein spezifischerer Ansatz, der nur verwendet werden sollte, wenn beide gelten die folgenden Bedingungen:
- Die komprimierte Audioquelle ist ein Stream von AAC-Frames, die in ADTS-Headern enthalten sind.
- Dieser Stream wird von der Anwendung verwaltet. Die Daten befinden sich nicht in einer Netzwerkressource, deren Kennung ein URI ist, oder in einer lokalen Datei, deren Kennung ein Dateideskriptor ist.
Die Anwendung sollte anfangs eine Reihe gefüllter Puffer in die Android-Pufferwarteschlange einreihen. Jeder Puffer enthält einen oder mehrere vollständige ADTS-AAC-Frames. Der Callback für die Android-Zwischenspeicherwarteschlange wird ausgelöst, nachdem jeder Zwischenspeicher geleert wurde. Der Callback-Handler sollte den Puffer wieder auffüllen, neu in die Warteschlange stellen und dann zurückkehren. Die Anwendung muss keine codierten Puffer im Blick behalten. Die Liste der Rückrufparameter enthält ausreichend Informationen, um den Puffer anzugeben, der als Nächstes in die Warteschlange gestellt werden soll. Das Ende des Streams wird explizit markiert, indem ein EOS-Element in die Warteschlange gestellt wird. Nach EOS sind keine Warteschlangen mehr zulässig.
Wir empfehlen, vollständige ADTS-AAC-Puffer bereitzustellen, um einen Dekoder-Stau zu vermeiden. Das kann beispielsweise passieren, wenn Ihre App vom Rückruf der Android-Pufferwarteschlange zurückkehrt, ohne einen weiteren vollständigen Puffer in die Warteschlange einzufügen. Das Ergebnis eines Decodermangels ist nicht angegeben.
Abgesehen von der Datenquelle entspricht die Streaming-Dekodierungsmethode derjenigen, die unter Audio in PCM decodieren beschrieben wird.
Trotz der ähnlichen Namen ist eine Android-Zwischenspeicherwarteschlange nicht
wie bei einer einfachen Android-Zwischenspeicherwarteschlange. Der Streaming-Decoder verwendet beide Arten von Pufferwarteschlangen: eine Android-Pufferwarteschlange für die ADTS-AAC-Datenquelle und eine einfache Android-Pufferwarteschlange für die PCM-Datensenke. Weitere Informationen zur einfachen Zwischenspeicher-Warteschlangen-API von Android finden Sie unter Android
einfache Datensuche und -schnittstelle für Zwischenspeicherwarteschlangen.
Weitere Informationen zur Android Buffer Queue API finden Sie in der Datei index.html
in
das Verzeichnis docs/Additional_library_docs/openmaxal/
im Installationsstammverzeichnis.
Das Format decodierter PCM-Daten über Metadaten bestimmen
Die SLMetadataExtractionItf
-Schnittstelle ist Teil der Referenzspezifikation.
Die Metadatenschlüssel, die das tatsächliche Format der decodierten PCM-Daten angeben, sind jedoch spezifisch für Android. Diese Metadatenschlüssel werden in der OpenSLES_AndroidMetadata.h
-Headerdatei definiert.
Diese Headerdatei befindet sich im Stammverzeichnis der Installation im Verzeichnis /sysroot/usr/include/SLES
.
Die Indizes für Metadatenschlüssel sind sofort verfügbar, nachdem
Die Ausführung der Methode Object::Realize()
wird abgeschlossen. Die verknüpften Werte sind jedoch nicht
verfügbar sind, bis die App die ersten codierten Daten decodiert hat. Es empfiehlt sich, nach dem Aufruf der Object::Realize
-Methode im Hauptthread nach den Schlüsselindizes zu fragen und die Metadatenwerte im PCM-Format im Callback-Handler der einfachen Android-Pufferwarteschlange beim ersten Aufruf zu lesen. Im Beispielcode im NDK-Paket finden Sie Beispiele für die Verwendung dieser Schnittstelle.
Die Namen der Metadatenschlüssel sind stabil, die Schlüsselindizes sind jedoch nicht dokumentiert und können sich ändern. Eine Anwendung sollte nicht voraussetzen, dass Indexe sind über verschiedene Ausführungsausführungen hinweg persistent und sollten nicht davon ausgehen, Mehrere Objektinstanzen haben innerhalb eines Durchlaufs gemeinsame Indexe.
Gleitkommadaten
Eine App, die auf Android 5.0 (API-Level 21) oder höher ausgeführt wird, kann Daten im Format „Single Precision Floating Point“ an einen AudioPlayer senden.
Im folgenden Beispielcode wird mit der Methode Engine::CreateAudioPlayer()
ein Audioplayer erstellt, der Gleitkommadaten verwendet:
#include <SLES/OpenSLES_Android.h> ... SLAndroidDataFormat_PCM_EX pcm; pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; pcm.numChannels = 2; pcm.sampleRate = SL_SAMPLINGRATE_44_1; pcm.bitsPerSample = 32; pcm.containerSize = 32; pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; ... SLDataSource audiosrc; audiosrc.pLocator = ... audiosrc.pFormat = &pcm;