OSTRZEŻENIE: standard OpenSL ES został wycofany. Deweloperzy powinni używać oprogramowania open source Biblioteka obojów dostępna na GitHubie. Oboe to otoczka w C++, która udostępnia interfejs API bardzo podobny do AAudio. Oboe wywołuje AAudio, gdy jest ono dostępne, a w przeciwnym razie przechodzi do OpenSL ES.
OpenSL ES for Android rozszerza referencyjną specyfikację OpenSL ES w taki sposób, aby była zgodna z z systemem Android oraz możliwościami i elastycznością platformy.
Definicja interfejsu API rozszerzeń na Androida znajduje się w pliku OpenSLES_Android.h
oraz w zawartych w nim plikach nagłówków. Skontaktuj się z firmą OpenSLES_Android.h
. Ten plik znajduje się w katalogu sysroot/usr/include/SLES
w katalogu głównym instalacji. O ile nie zaznaczono inaczej, wszystkie interfejsy są jawne.
Te rozszerzenia ograniczają możliwość przenoszenia aplikacji do
innych implementacji OpenSL ES, ponieważ są one typowe dla Androida. Aby rozwiązać ten problem,
unikanie rozszerzeń lub wykluczanie ich za pomocą #ifdef
podczas kompilowania.
W tabeli poniżej znajdziesz interfejsy i lokalizatory danych obsługiwane przez Androida OpenSL ES dla każdego typu obiektu. Wartości Tak w komórkach oznaczają interfejsy i dane. dostępne dla poszczególnych typów obiektów.
Funkcja | Odtwarzacz audio | Rejestratory dźwięku | Silnik | Miks wyjściowy |
---|---|---|---|---|
Kolejka bufora w Androidzie | Tak: źródło (dekodowanie) | Nie | Nie | Nie |
Konfiguracja Androida | Tak | Tak | Nie | Nie |
Efekt Androida | Tak | Nie | Nie | Tak |
Funkcje efektów w Androidzie | Nie | Nie | Tak | Nie |
Wysyłanie efektu na Androidzie | Tak | Nie | Nie | Nie |
Prosta kolejka bufora na Androidzie | Tak: źródło (odtwarzanie) lub ujście (dekodowanie) | Tak | Nie | Nie |
Lokalizator danych kolejki bufora w Androidzie | Tak: źródło (odkodowanie) | Nie | Nie | Nie |
Lokalizator danych deskryptora pliku w Androidzie | Tak: źródło | Nie | Nie | Nie |
Lokalizator danych prostej kolejki bufora na Androidzie | Tak: źródło (odtwarzanie) lub ujście (dekodowanie) | Tak: zlew | Nie | Nie |
Interfejs konfiguracji Androida
Interfejs konfiguracji Androida umożliwia ustawianie parametrów obiektów na podstawie platformy. Ten interfejs różni się od innych plików OpenSL ES
interfejs w wersji 1.0.1, pod którym aplikacja może z niego korzystać przed utworzeniem instancji odpowiedniego obiektu; a więc
możesz skonfigurować obiekt przed jego utworzeniem. Plik nagłówka OpenSLES_AndroidConfiguration.h
, który znajduje się w katalogu /sysroot/usr/include/SLES
, zawiera te dostępne klucze i wartości konfiguracji:
- Typ strumienia dla odtwarzaczy audio (domyślnie
SL_ANDROID_STREAM_MEDIA
). - Profil nagrywania dla rejestratorów dźwięku (domyślnie
SL_ANDROID_RECORDING_PRESET_GENERIC
).
Ten fragment kodu pokazuje, jak ustawić typ strumienia audio na urządzeniu z Androidem. gracz:
// 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.
Aby skonfigurować preset dla rejestratora dźwięku, możesz użyć podobnego kodu:
// ... 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));
Interfejsy efektów Androida
Interfejsy efektów, wysyłania efektów i możliwości efektów w Androidzie zapewniają ogólny mechanizm, który umożliwia aplikacji wysyłanie zapytań o efekty dźwiękowe specyficzne dla urządzenia i ich używanie. Producenci urządzeń powinni udokumentować wszystkie dostępne efekty dźwiękowe, które oferują.
Przenośne aplikacje powinny używać interfejsów OpenSL ES 1.0.1 do efektów dźwiękowych zamiast rozszerzeń efektów Androida.
Lokalizator danych deskryptora pliku w Androidzie
Lokalizator danych opisu pliku Androida umożliwia określenie źródła odtwarzacza audio jako otwartego opisu pliku z dostępem do odczytu. Dane muszą być w formacie MIME.
To rozszerzenie jest szczególnie przydatne w połączeniu z menedżerem zasobów natywnych, ponieważ aplikacja odczytuje zasoby z pakietu APK za pomocą deskryptora pliku.
Prosty lokalizator danych i interfejs kolejki bufora na Androidzie
W specyfikacji referencyjnej OpenSL ES 1.0.1 kolejki buforów mogą być używane tylko w odtwarzaczach audio i są zgodne z PCM oraz innymi formatami danych. Lokalizator danych i specyfikacja interfejsu prostej kolejki bufora na Androidzie to: identyczne ze specyfikacją referencyjną, z 2 wyjątkami:
- Z prostymi kolejkami buforowania na Androidzie możesz korzystać z nagrywarek i odtwarzaczy audio.
- W przypadku tych kolejek możesz używać tylko formatu danych PCM.
Podczas nagrywania aplikacja powinna umieszczać puste bufory w kole. Gdy zarejestrowane wywołanie zwrotne po zakończeniu zapisywania danych w buforze, aplikacja może odczytują dane z tego bufora.
Odtwarzanie działa w ten sam sposób. Na potrzeby przyszłego kodu źródłowego zgodności, ale sugerujemy, by w aplikacjach na Androida i kolejki buforów zamiast kolejek buforów OpenSL ES 1.0.1.
Zachowanie kolejki bufora
Implementacja na Androidzie nie uwzględnia wymagań specyfikacji referencyjnej, które mówią, że kursor odtwarzania powinien wrócić do początku bufora odtwarzanego obecnie, gdy odtwarzanie wejdzie w stan SL_PLAYSTATE_STOPPED
. Może ona dostosować się do tego zachowania lub opuścić miejsce odtwarzania.
kursor nie został zmieniony.
Dlatego aplikacja nie może zakładać, że zachodzi któreś z tych działań. Dlatego po przejściu na SL_PLAYSTATE_STOPPED
musisz wyraźnie wywołać metodę BufferQueue::Clear()
. W ten sposób ustawisz kolejkę buforów w znanym stanie.
Podobnie nie ma specyfikacji określającej, czy wyzwalacz wywołania kolejki buforowej musi być przejściem do SL_PLAYSTATE_STOPPED
czy wykonaniem BufferQueue::Clear()
. Dlatego nie zalecamy tworzenia zależności
jeden lub drugi, aplikacja powinna obsługiwać oba te tryby.
Interfejsy dynamiczne podczas tworzenia obiektu
Dla wygody implementacja OpenSL ES 1.0.1 na Androidzie umożliwia aplikacji określanie interfejsów dynamicznych podczas tworzenia instancji obiektu.
Jest to alternatywa dla korzystania z elementu DynamicInterfaceManagement::AddInterface()
aby dodać te interfejsy po utworzeniu instancji.
Zgłaszanie rozszerzeń
Istnieją 3 metody sprawdzania, czy platforma obsługuje rozszerzenia na Androida. Te to:
Engine::QueryNumSupportedExtensions()
Engine::QuerySupportedExtension()
Engine::IsExtensionSupported()
Każda z tych metod zwraca wartość ANDROID_SDK_LEVEL_<API-level>
, gdzie API-level
to poziom interfejsu API platformy, np. ANDROID_SDK_LEVEL_23
.
Poziom interfejsu API platformy 9 lub nowszy oznacza, że platforma obsługuje rozszerzenia.
Dekodowanie dźwięku na PCM
W tej sekcji opisano przestarzałe rozszerzenie OpenSL ES 1.0.1 na Androida, które służy do dekodowania zakodowanego strumienia na PCM bez natychmiastowego odtwarzania. W tabeli poniżej znajdziesz zalecenia dotyczące korzystania z tego rozszerzenia i jego alternatyw.
Poziom interfejsu API | Alternatywy |
---|---|
15 i mniejsze | kodek open source z odpowiednią licencją, |
16–20 |
Klasa MediaCodec lub kodek open source z odpowiednią licencją
|
21 i więcej |
NDK MediaCodec w plikach nagłówków <media/NdkMedia*.h> , klasie MediaCodec lub kodeku open source z odpowiednią licencją
|
Uwaga: obecnie nie ma dokumentacji wersji interfejsu API MediaCodec
przeznaczonej do NDK. Możesz jednak skorzystać z przykładowego kodu native-codec.
Standardowy odtwarzacz audio odtwarza dźwięk na urządzeniu audio, określając miks wyjściowy jako ujście danych. Rozszerzenie na Androida różni się tym, że odtwarzacz audio działa jako dekoder, jeśli aplikacja określiła źródło danych jako identyfikator URI lub lokalizator danych w descrypcji pliku na Androida opisanej za pomocą formatu danych MIME. W takim przypadku odbiornikiem danych jest lokalizator danych z prostej kolejki buforowej Androida, który używa formatu PCM.
Ta funkcja jest przeznaczona przede wszystkim dla gier do wstępnego wczytywania zasobów audio po przejściu na
poziomem gry, który jest podobny do funkcji, które SoundPool
co zapewnia klasa.
Aplikacja powinna początkowo umieścić w kole zestaw pustych buforów w prostej kolejce buforów Androida. Następnie aplikacja wypełnia bufory danymi z PCM. Prosty Android wywołanie zwrotne kolejki bufora jest uruchamiane po wypełnieniu każdego bufora. Proces obsługi wywołania zwrotnego danych PCM, ponownie dodaje do kolejki pusty bufor, a potem powraca. Aplikacja jest odpowiedzialna za śledzenie odkodowanych buforów; lista parametrów wywołania zwrotnego nie zawiera wystarczających informacji, aby wskazać bufor zawierający dane lub bufor, który powinien zostać umieszczony w kolejce jako następny.
Źródło danych niejawnie podaje koniec strumienia (EOS), przesyłając
SL_PLAYEVENT_HEADATEND
na końcu strumienia. Po odkodowaniu aplikacji
wszystkich otrzymanych danych, nie wywołuje już więcej wywołań zwrotnych kolejki buforowej w Androidzie.
Format danych PCM ujścia zwykle jest zgodny z formatem zakodowanego źródła danych pod względem częstotliwości próbkowania, liczby kanałów i głębi bitowej. Możesz jednak odkodować plik z inną częstotliwością próbkowania, liczbą kanałów lub głębią bitową. Informacje o przepisach umożliwiających wykrywanie rzeczywistego formatu PCM znajdziesz tutaj: Określ format zdekodowanych danych PCM za pomocą metadanych.
Funkcja dekodowania PCM w OpenSL ES na Androida obsługuje pauzę i pierwotny przeskok. Nie obsługuje natomiast regulacji głośności, efektów, odtwarzania w pętli ani szybkości odtwarzania.
W zależności od implementacji platformy dekodowanie może wymagać zasobów. które nie mogą być bezczynne. Dlatego zalecamy zapewnienie wystarczającej liczby pustych buforów PCM, ponieważ w przeciwnym razie dekoder nie będzie miał wystarczającej ilości danych. Może się tak zdarzyć, jeśli aplikacja wróci z odwołania z prostej kolejki buforów Androida bez dodania kolejnego pustego bufora. Skutkiem braku dekodera jest nieokreślone, ale może obejmować: usunięcie zdekodowanego dane PCM, wstrzymanie procesu dekodowania lub całkowite zakończenie dekodera.
Uwaga: aby dekodować zakodowany strumień do formatu PCM, ale nie odtwarzać go od razu, w przypadku aplikacji działających na Androidzie 4.x (poziomy interfejsu API 16–20) zalecamy użycie klasy MediaCodec
.
W przypadku nowych aplikacji działających na Androidzie 5.0 (poziom interfejsu API 21) lub nowszym zalecamy użycie odpowiednika NDK, <NdkMedia*.h>
. Te pliki nagłówka znajdują się w katalogu media/
w głównym katalogu instalacji.
Dekodowanie strumieniowego ADTS AAC na PCM
Odtwarzacz dźwięku działa jak dekoder strumieniowy, jeśli źródłem danych jest Lokalizator danych kolejki bufora Androida używający formatu danych MIME ujście to lokalizator danych kolejki bufora w Androidzie, który korzysta z formatu danych PCM. Skonfiguruj format danych MIME w ten sposób:
- Kontener:
SL_CONTAINERTYPE_RAW
- Ciąg znaków typu MIME:
SL_ANDROID_MIME_AACADTS
Ta funkcja jest przeznaczona przede wszystkim dla aplikacji do odtwarzania multimediów, które obsługuje dźwięk AAC, ale potrzebuje niestandardowego przetwarzania dźwięku przed rozpoczęciem odtwarzania. Większość aplikacji, które potrzebują dekodowania dźwięku na PCM. należy użyć metody omówionej w sekcji Dekodowanie dźwięku do PCM, ponieważ jest prostsza i obsługuje więcej formatów audio. Opisana technika bardziej specjalistyczne podejście, które należy stosować tylko wtedy, obowiązują warunki:
- Skompresowane źródło dźwięku to strumień ramek AAC zawartych w nagłówkach ADTS.
- Tą transmisją zarządza aplikacja. Dane nie znajdują się w: zasobu sieciowego, którego identyfikator jest identyfikatorem URI lub w pliku lokalnym, którego identyfikator to deskryptor pliku.
Aplikacja powinna początkowo umieścić w kole buforów Androida zestaw wypełnionych buforów. Każdy bufor zawiera co najmniej 1 pełny pakiet ADTS AAC. Wywołanie zwrotne kolejki bufora Androida jest uruchamiane po opróżnieniu każdego bufora. Moduł obsługi wywołania zwrotnego powinien ponownie wypełnić i odświeżyć bufor, a następnie zwrócić go. Aplikacja nie musi śledzić zakodowanych buforów. parametr wywołania zwrotnego zawiera informacje wystarczające do wskazania bufora, który powinien zostać dodany do kolejki w następnej kolejności. Koniec strumienia jest wyraźnie oznaczony przez dodanie elementu EOS do kolejki. Po zakończeniu EOS nie można już umieszczać w kolejkach.
Zalecamy, aby zapewnić pełne bufory AAC ADTS, aby uniknąć niedoboru dekodera. Może się tak zdarzyć, jeśli na przykład aplikacja zwraca wywołanie zwrotne kolejki bufora Androida bez umieszczania w kolejce kolejnego pełnego bufora. Wynik braku dostępu do dekodera jest nieokreślony.
Pod każdym względem, z wyjątkiem źródła danych, metoda dekodowania strumieniowego jest taka sama jak opisana w artykule Dekodowanie dźwięku do formatu PCM.
Pomimo podobieństwa nazw, kolejka bufora w Androidzie nie
to samo co kolejka bufora w Androidzie. Dekoder strumieniowy używa obu rodzajów kolejek buforowych: kolejki buforowej Androida dla źródła danych ADTS AAC i prostej kolejki buforowej Androida dla odbiornika danych PCM. Więcej informacji o interfejsie i lokalizatorze danych kolejki prostych buforów na Androidzie znajdziesz w artykule Interfejs i lokalizator danych kolejki prostych buforów na Androidzie.
Więcej informacji o interfejsie API kolejki bufora w Androidzie znajdziesz w pliku index.html
w
w katalogu docs/Additional_library_docs/openmaxal/
poniżej katalogu głównego instalacji.
Określ format dekodowanych danych PCM za pomocą metadanych
Interfejs SLMetadataExtractionItf
jest częścią specyfikacji referencyjnej.
Jednak klucze metadanych, które wskazują rzeczywisty format zdekodowanych danych PCM, są charakterystyczne dla
na urządzeniu z Androidem. Te klucze metadanych są zdefiniowane w pliku nagłówka OpenSLES_AndroidMetadata.h
.
Ten plik nagłówka znajduje się w katalogu głównym instalacji, w sekcji
Katalog /sysroot/usr/include/SLES
.
Indeksy kluczy metadanych są dostępne natychmiast po zakończeniu wykonywania metody Object::Realize()
. Powiązane wartości nie są jednak
dostępne do momentu zdekodowania przez aplikację pierwszego zakodowanego danych. Dobrą praktyką jest wysyłanie zapytań o kluczowe indeksy w głównym wątku po wywołaniu metody Object::Realize
oraz odczytywanie wartości metadanych w formacie PCM w prostym obsłudze wywołania kolejki buforów Androida po jej pierwszym wywołaniu. Przykłady korzystania z tego interfejsu znajdziesz w przykładowym kodzie w pakiecie NDK.
Nazwy kluczy metadanych są stabilne, ale indeksy kluczy nie są udokumentowane i mogą ulec zmianie. Aplikacja nie powinna zakładać, że indeksy są trwałe w różnych przebiegach wykonania, ani nie powinna zakładać, że indeksy są współdzielone przez wiele wystąpień obiektów w tym samym przebiegu.
Dane zmiennoprzecinkowe
Aplikacja działająca na Androidzie 5.0 (poziom interfejsu API 21) lub nowszym może przekazywać dane do AudioPlayera w formacie zmiennoprzecinkowym o pojedynczej precyzji.
W poniższym przykładowym kodzie metoda Engine::CreateAudioPlayer()
tworzy odtwarzacz dźwięku
który korzysta z danych zmiennoprzecinkowych:
#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;