Android-Erweiterungen

OpenSL ES for Android erweitert die OpenSL ES-Referenzspezifikation zur Kompatibilität mit Android und die Leistungsfähigkeit 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. Diese Datei befindet sich im Installationsstamm im sysroot/usr/include/SLES-Verzeichnis. Soweit nicht anders angegeben ist, sind alle Schnittstellen explizit.

Diese Erweiterungen beschränken die Übertragbarkeit Ihrer Anwendung auf anderen 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.

Die folgende Tabelle zeigt die Android-spezifischen Oberflächen und Data Locator-Funktionen, die von OpenSL ES von Android unterstützt werden für jeden Objekttyp. Die Ja-Werte in den Zellen geben die Schnittstellen und Daten an. finden, die für jeden Objekttyp verfügbar sind.

Funktion Audio player Audiorekorder Motor Ausgabemix
Android-Zwischenspeicherwarteschlange Ja: Quelle (decodieren) Nein Nein Nein
Android-Konfiguration Ja Ja Nein Nein
Android-Effekt Ja Nein Nein Ja
Android-Effektfunktionen Nein Nein Ja Nein
Android-Effekt senden Ja Nein Nein Nein
Einfache Android-Zwischenspeicherwarteschlange Ja: Quelle (Wiedergabe) oder Senke (Decodierung) Ja Nein Nein
Datensuche für Android-Zwischenspeicherwarteschlangen Ja: Quelle (decodieren) Nein Nein Nein
Datensuche für Android-Dateideskriptoren Ja: Quelle Nein Nein Nein
Einfache Android-Zwischenspeicherwarteschlange Ja: Quelle (Wiedergabe) oder Senke (Decodierung) Ja: Senke Nein Nein

Android-Konfigurationsoberfläche

Über die Android-Konfigurationsoberfläche können Sie plattformspezifische Parameter für Objekte. 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, wie der Typ des Android-Audiostreams für ein Audio festgelegt wird. Player:

// 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));

Oberflächen für 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.

Datensuche für Android-Dateideskriptoren

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 liest die App Assets aus dem APK über einen Dateideskriptor.

Einfache Android-Zwischenspeicherwarteschlange und -schnittstelle

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 Android-Spezifikationen für die einfache Zwischenspeicherwarteschlange identisch mit der Referenzspezifikation, bis auf zwei Ausnahmen:

  • Sie können einfache Zwischenspeicherwarteschlangen von Android mit Audiorekordern und Audioplayern verwenden.
  • Bei diesen Warteschlangen können Sie nur das PCM-Datenformat verwenden.

Für die Aufzeichnung sollte Ihre App leere Zwischenspeicher in die Warteschlange stellen. 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 Anwendungen die einfache Android-Version Pufferwarteschlangen anstelle von OpenSL ES 1.0.1-Pufferwarteschlangen erstellt.

Verhalten der Pufferwarteschlange

Die Android-Implementierung enthält nicht das die Anforderung der Spezifikation, dass der Wiedergabe-Cursor an den Anfang zurückkehrt, des Zwischenspeichers, der gerade abgespielt wird, wenn die Wiedergabe in den SL_PLAYSTATE_STOPPED wechselt Bundesstaat. 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. Dementsprechend wird sollten Sie die Methode BufferQueue::Clear() nach einem Übergang zu SL_PLAYSTATE_STOPPED. 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(). Daher empfehlen wir, keine Abhängigkeit von das eine oder das andere, sollte Ihre App beides verarbeiten können.

Dynamische Schnittstellen bei der Objekterstellung

Der Einfachheit halber ist die Android-Implementierung von OpenSL ES 1.0.1 ermöglicht Ihrer App, dynamische Schnittstellen anzugeben, wenn sie ein Objekt instanziiert. Dies ist eine Alternative zur Verwendung von DynamicInterfaceManagement::AddInterface() um diese Schnittstellen nach der Instanziierung hinzuzufügen.

Berichte zu Erweiterungen

Es gibt drei Methoden, um herauszufinden, ob die Plattform Android-Erweiterungen unterstützt. Diese Methoden:

  • 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
15 und jünger Ein Open-Source-Codec mit einer geeigneten Lizenz
16 bis 20 Die Klasse MediaCodec oder ein Open-Source-Codec mit einer entsprechenden Lizenz
21 und älter NDK MediaCodec in den <media/NdkMedia*.h>-Headerdateien, der MediaCodec-Klasse oder einen Open-Source-Codec mit einer entsprechenden Lizenz

Hinweis: Für die NDK-Version der MediaCodec API gibt es derzeit keine Dokumentation. Sie können jedoch finden Sie in den <ph type="x-smartling-placeholder"></ph> nativen Codec-Beispielcode.

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. Die einfache Android-Version Der Pufferwarteschlangen-Callback wird ausgelöst, nachdem jeder Puffer gefüllt wurde. 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 in die Warteschlange.

Die Datenquelle meldet implizit das Ende des Streams (EOS), indem sie eine SL_PLAYEVENT_HEADATEND-Ereignis am Ende des Streams ein. Nachdem die App decodiert wurde alle empfangenen Daten verarbeitet, werden keine weiteren Aufrufe an den Android-Callback für die einfache Zwischenspeicherwarteschlange gesendet.

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 Bereitstellung zur Erkennung des tatsächlichen PCM-Formats finden Sie unter Format der decodierten PCM-Daten über Metadaten bestimmen

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 kann die Decodierung Ressourcen erfordern die nicht inaktiv sein können. 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 umfassen: Löschen der decodierten PCM-Daten, Unterbrechung des Decodierungsvorgangs oder vollständiges Beenden des Decoders.

Hinweis: Um einen codierten Stream in PCM zu decodieren, ohne sie sofort wiederzugeben, für Apps, die auf Android 4.x (API-Level 16–20) empfehlen wir die Verwendung der 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 Header-Dateien befinden sich das Verzeichnis media/ im Installationsstammverzeichnis.

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 Eine Netzwerkressource, deren Kennung ein URI ist, oder in einer lokalen Datei mit der Kennung eine Dateibeschreibung.

Die Anwendung sollte anfangs eine Reihe gefüllter Puffer in die Android-Zwischenspeicherwarteschlange stellen. Jeder Zwischenspeicher 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 neu auffüllen, wieder in die Warteschlange stellen und dann zurückkehren. Die Anwendung muss keine codierten Zwischenspeicher verfolgen. Callback-Parameter Liste enthält genügend Informationen, um den Zwischenspeicher anzugeben, der als Nächstes in die Warteschlange eingereiht 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 Ihnen, ADTS AAC puffern, um zu verhindern, dass der Decoder ausgehungert wird. Das kann zum Beispiel passieren, vom Android-Pufferwarteschlangen-Callback zurückgegeben, ohne einen weiteren vollen Puffer in die Warteschlange einzureihen. Das Ergebnis eines Decodermangels ist nicht angegeben.

Mit Ausnahme der Datenquelle ist die Streaming-Decodierungsmethode in jeder Hinsicht die gleiche wie die unter Audio in PCM decodieren beschrieben.

Trotz der ähnlichen Namen ist eine Android-Zwischenspeicherwarteschlange nicht wie bei einer einfachen Android-Zwischenspeicherwarteschlange. Streaming-Decoder verwendet beide Arten von Pufferwarteschlangen: eine Android-Pufferwarteschlange für das ADTS. AAC-Datenquelle und eine einfache Android-Zwischenspeicherwarteschlange für die PCM-Daten Sinken. 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 decodierter PCM-Daten angeben, sind spezifisch für Android Diese Metadatenschlüssel werden in der Headerdatei OpenSLES_AndroidMetadata.h definiert. Diese Headerdatei befindet sich im Installationsstamm im /sysroot/usr/include/SLES-Verzeichnis.

Die Indizes für Metadatenschlüssel stehen sofort nach der 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. Eine gute die Schlüsselindizes im Hauptthread abzufragen, nachdem die Methode Object::Realize aufgerufen wurde, und die Metadatenwerte im PCM-Format in der einfachen Android-Version zu lesen. Puffer-Warteschlangen-Rückruf-Handler zu erstellen, wenn er zum ersten Mal aufgerufen wird. Informationen hierzu finden Sie in der Beispielcode im NDK-Paket.

Die Namen der Metadatenschlüssel sind stabil, aber die Schlüsselindizes sind 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 mit Android 5.0 (API-Level 21) und höher kann Daten an einen AudioPlayer in Gleitkommazahl mit einfacher Genauigkeit.

Im folgenden Beispielcode wird mit der Methode Engine::CreateAudioPlayer() ein Audioplayer erstellt. mit Gleitkommadaten:

#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;
Weitere Informationen zu Gleitkomma-Audio auf der Seite „Audio-Sampling“.