Rozszerzenia na Androida

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 dla rozszerzeń na Androida znajduje się w tym języku: OpenSLES_Android.h i dołączone pliki nagłówka. Skontaktuj się z firmą OpenSLES_Android.h . Ten plik znajduje się w katalogu głównym instalacji, w folderze Katalog sysroot/usr/include/SLES. Chyba że nie 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 dźwięku 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 na Androida Tak Nie Nie Tak
Funkcje efektów w Androidzie Nie Nie Tak Nie
Wysyłanie efektów Androida Tak Nie Nie Nie
Prosta kolejka bufora w Androidzie Tak: źródło (odtwarzanie) lub ujście (dekodowanie) Tak Nie Nie
Lokalizator danych kolejki bufora w Androidzie Tak: źródło (dekodowanie) Nie Nie Nie
Lokalizator danych deskryptora plików na Androida Tak: źródło Nie Nie Nie
Prosty lokalizator danych kolejki bufora na Androidzie Tak: źródło (odtwarzanie) lub ujście (dekodowanie) Tak: zlew Nie Nie

Interfejs konfiguracyjny Androida

Interfejs konfiguracji Androida pozwala określić związanych z daną platformą. 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. OpenSLES_AndroidConfiguration.h znajduje się pod adresem /sysroot/usr/include/SLES, dokumentuje następujące dostępne klucze i wartości konfiguracji:

  • Typ strumienia w odtwarzaczach audio (domyślnie SL_ANDROID_STREAM_MEDIA).
  • Profil nagrywania dla dyktafonów (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.

Możesz skorzystać z podobnego kodu, aby skonfigurować gotowe ustawienia dla dyktafonu:

// ... 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 na Androida

Interfejsy funkcji efektu, wysyłania efektów i efektów w Androidzie zapewniają ogólny mechanizm wysyłania zapytań i korzystania z treści w zależności od urządzenia efekty dźwiękowe. Producenci urządzeń powinni udokumentować wszystkie dostępne efekty dźwiękowe związane z danym urządzeniem. jakie zapewniają.

W przypadku efektów dźwiękowych aplikacje przenośne powinny używać interfejsów API OpenSL ES 1.0.1 do efektów dźwiękowych, a nie Androida. z efektami.

Lokalizator danych deskryptora plików na Androida

Lokalizator danych deskryptora plików na Androida umożliwia określenie źródła odtwarzacza dźwięku jako otwartego deskryptora plików z uprawnieniami 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

Zgodnie ze specyfikacją referencyjną OpenSL ES 1.0.1 kolejki buforowe mogą być używane tylko przez odtwarzacze dźwięku i są to: zgodne z PCM i innymi formatami danych. Lokalizator danych i specyfikacja interfejsu prostej kolejki bufora na Androidzie to: identyczne ze specyfikacją referencyjną, z 2 wyjątkami:

  • Możesz używać prostych kolejek buforowych na Androidzie w przypadku dyktafonów i odtwarzaczy dźwięku.
  • W przypadku tych kolejek możesz używać tylko formatu danych PCM.

Na potrzeby nagrywania aplikacja powinna umieszczać puste bufory w kolejce. Gdy zarejestrowane wywołanie zwrotne po zakończeniu zapisywania danych w buforze, aplikacja może odczytują dane z tego bufora.

Tak samo działa odtwarzanie. 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.

Działanie kolejki buforów

Implementacja Androida nie obejmuje odnosi się do wymagania specyfikacji, że kursor odtwarzania musi wrócić na początek aktualnie odtwarzanego bufora po rozpoczęciu odtwarzania w trybie SL_PLAYSTATE_STOPPED stanu. 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 należy bezpośrednio wywołać metodę BufferQueue::Clear() po przejściu do SL_PLAYSTATE_STOPPED Spowoduje to ustawienie kolejki bufora w znany stan.

Nie istnieje również żadna specyfikacja, która określa, czy aktywator wywołania zwrotnego kolejki bufora musi jest przejściem do SL_PLAYSTATE_STOPPED lub wykonaniem BufferQueue::Clear() Dlatego nie zalecamy tworzenia zależności jeden lub drugi, aplikacja powinna obsługiwać oba te tryby.

Interfejsy dynamiczne podczas tworzenia obiektów

Dla wygody implementacja OpenSL ES 1.0.1 na Androida pozwala aplikacji na 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 ANDROID_SDK_LEVEL_<API-level>, gdzie API-level to poziom interfejsu API platformy. na przykład ANDROID_SDK_LEVEL_23. Poziom interfejsu API platformy równy 9 lub wyższy oznacza, że platforma obsługuje rozszerzenia.

Dekodowanie dźwięku na PCM

Ta sekcja opisuje wycofane rozszerzenie OpenSL ES 1.0.1 przeznaczone na Androida. do dekodowania zakodowanego strumienia do PCM bez natychmiastowego odtwarzania. W tabeli poniżej znajdziesz zalecenia dotyczące tego rozszerzenia oraz jego alternatyw.

Poziom interfejsu API Alternatywy
15 i mniej kodek open source z odpowiednią licencją,
Od 16 do 20 Klasa MediaCodec lub kodek open source z odpowiednią licencją.
21 i więcej NDK MediaCodec w plikach nagłówka <media/NdkMedia*.h>, MediaCodec lub kodek open source z odpowiednią licencją.

Uwaga: Obecnie nie istnieje dokumentacja dla wersji NDK interfejsu API MediaCodec. Pamiętaj jednak: znajdziesz w natywny-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 dźwięku działa jako dekoder, jeśli aplikacja określi źródło danych jako identyfikator URI lub Androida Lokalizator danych deskryptora pliku opisany przy użyciu formatu danych MIME. W takim przypadku ujście danych jest prosty lokalizator danych kolejki bufora na Androida, który korzysta z formatu danych 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 kolejce pustych bufory w prostym interfejsie w kolejce bufora. 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 zdekodowanych buforów; lista parametrów wywołania zwrotnego nie zawiera wystarczających informacji do wskazania bufora zawierającego dane lub bufora, który należy dodano do kolejki.

Ź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 zdekodować częstotliwość próbkowania, liczba kanałów lub głębia bitowa. Informacje o przepisach umożliwiających wykrywanie rzeczywistego formatu PCM znajdziesz tutaj: Określ format zdekodowanych danych PCM za pomocą metadanych.

Funkcja dekodowania OpenSL ES na Androidzie w PCM obsługuje wstrzymywanie i początkowe przewijanie. nie obsługuje sterowanie głośnością, efekty, zapętlenie czy szybkość odtwarzania.

W zależności od implementacji platformy dekodowanie może wymagać zasobów. które nie mogą być bezczynne. Dlatego zalecamy podanie wystarczająca liczba pustych buforów PCM; w przeciwnym razie dekoder będzie głodny. Może się tak zdarzyć, na przykład jeśli aplikacja wraca z wywołania zwrotnego kolejki bufora w Androidzie bez umieszczenie kolejnego pustego bufora w kolejce. 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 zdekodować zakodowany strumień do PCM, ale nie odtwarzać go od razu, w przypadku aplikacji działających na Android 4.x (poziom 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 pakietu NDK odpowiednik: <NdkMedia*.h>. Te pliki nagłówka znajdują się w w katalogu media/ w katalogu głównym instalacji.

Dekodowanie strumieniowego przesyłania danych AAC z ADTS do 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 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.
  • Strumień 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ć zestaw wypełnionych buforów w kolejce buforów Androida. Każdy bufor zawiera co najmniej jedną pełną klatkę AAC ADTS. Wywołanie zwrotne kolejki bufora Androida jest uruchamiane po opróżnieniu każdego bufora. Moduł obsługi wywołania zwrotnego powinien ponownie wypełnić bufor i umieścić go w kolejce, a następnie zwrócić. 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 podanie pełnych ADTS AAC buforuje, by nie głodować 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. Skutek braku dekodera jest nieokreślony.

Pod każdym względem z wyjątkiem źródła danych metoda dekodowania strumieniowego jest taka sama jak opisanego w artykule Dekodowanie dźwięku do PCM.

Pomimo podobieństwa nazw, kolejka bufora w Androidzie nie to samo co kolejka bufora w Androidzie. Dekoder strumieniowy korzysta z obu rodzajów kolejek bufora: kolejki bufora w Androidzie dla ADTS. Źródło danych AAC oraz prosta kolejka bufora danych w Androidzie dla danych PCM zlewozmywacz. Więcej informacji o interfejsie API prostej kolejki buforowej w Androidzie znajdziesz w artykule Android prosty lokalizator danych i interfejs kolejki bufora. 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 zdekodowanych 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 metoda Object::Realize() zakończy wykonywanie. Powiązane wartości nie są jednak dostępne do momentu zdekodowania przez aplikację pierwszego zakodowanego danych. Dobra ćwiczenie polega na wysyłaniu zapytań o kluczowe indeksy w wątku głównym po wywołaniu metody Object::Realize i odczytywanie wartości metadanych formatu PCM w prostej aplikacji Android modułu obsługi wywołania zwrotnego kolejki bufora przy pierwszym wywołaniu tej kolejki. Skonsultuj się z przykładowy kod w pakietu NDK, które zawiera przykłady pracy z tym interfejsem.

Nazwy kluczy metadanych są stałe, ale indeksy kluczy nie są udokumentowane mogą ulec zmianie. Aplikacja nie powinna zakładać, że indeksy są trwałe przy różnych uruchomieniach i nie należy zakładać, że wiele instancji obiektów współużytkuje indeksy podczas tego samego uruchomienia.

Dane zmiennoprzecinkowe

Aplikacja działająca w Androidzie 5.0 (poziom interfejsu API 21) lub nowszym może dostarczać dane do odtwarzacza AudioPlayer w: zmiennoprzecinkową o pojedynczej precyzji.

W podanym niżej 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;
Dowiedz się więcej o reklamach audio zmiennoprzecinkowych. na stronie Próbkowanie dźwięku.