Rozpocznij

OSTRZEŻENIE: OpenSL ES został wycofany. Deweloperzy powinni używać biblioteki Oboe typu open source, która jest dostępna na GitHubie. Oboe to kod w języku C++ zapewniający interfejs API podobny do AAudio. Oboe wywołuje AAudio, gdy jest ono dostępne, a gdy nie jest, używa OpenSL ES.

Ta sekcja zawiera informacje potrzebne do rozpoczęcia korzystania z interfejsów OpenSL ES API.

Dodawanie biblioteki OpenSL ES do aplikacji

Funkcje OpenSL ES można wywoływać z kodu C i C++. Aby dodać do aplikacji podstawowy zestaw funkcji OpenSL ES, dołącz plik nagłówka OpenSLES.h:

#include <SLES/OpenSLES.h>

Aby dodać rozszerzenia OpenSL ES na Androida, dołącz plik nagłówka OpenSLES_Android.h:

#include <SLES/OpenSLES_Android.h>

Gdy dodasz plik nagłówka OpenSLES_Android.h, automatycznie zostaną uwzględnione te nagłówki:

#include <SLES/OpenSLES_AndroidConfiguration.h>
#include <SLES/OpenSLES_AndroidMetadata.h>

Uwaga: te nagłówki nie są wymagane, ale są wyświetlane jako pomoc w poznawaniu interfejsu API.

Kompilacja i debugowanie

Możesz włączyć OpenSL ES do kompilacji, określając go w pliku Android.mk, który służy jako jeden z plików Maker systemu kompilacji NDK. Dodaj do Android.mk ten wiersz:

LOCAL_LDLIBS += -lOpenSLES

Aby zapewnić niezawodne debugowanie, zalecamy sprawdzenie wartości SLresult, którą zwraca większość interfejsów OpenSL ES API. Do debugowania możesz użyć assertów lub bardziej zaawansowanej logiki obsługi błędów. Żadna z tych metod nie zapewnia przewagi w pracy z OpenSL ES, ale jedna z nich może być bardziej odpowiednia w danym przypadku użycia.

W naszych przykładach używamy asercji, ponieważ pomagają one wykrywać nierealistyczne warunki, które wskazują na błąd w programowaniu. W przypadku innych warunków, które prawdopodobnie wystąpią w wersji produkcyjnej, użyliśmy jawnego przetwarzania błędów.

Wiele błędów interfejsu API powoduje wpis w logu oprócz kodu wyniku innego niż 0. Takie wpisy w dzienniku mogą zawierać dodatkowe szczegóły, które są szczególnie przydatne w przypadku stosunkowo złożonych interfejsów API, takich jak Engine::CreateAudioPlayer.

Możesz wyświetlić log z wiersza poleceń lub z Android Studio. Aby sprawdzić dziennik z poziomu wiersza poleceń, wpisz:

$ adb logcat

Aby przejrzeć logi w Android Studio, kliknij Widok > Okna narzędzi > Logcat. Więcej informacji znajdziesz w artykule Zapisywanie i wyświetlanie logów za pomocą narzędzia Logcat.

Przykładowy kod

Zalecamy użycie obsługiwanego i przetestowanego przykładowego kodu, który można wykorzystać jako model dla własnego kodu. Znajduje się on w folderach audio-echonative-audio w repozytorium GitHub android-ndk.

Uwaga: specyfikacja OpenSL ES 1.0.1 zawiera w załącznikach przykładowy kod (więcej informacji znajdziesz w rejestrze Khronos OpenSL ES). Przykłady w Załączniku B: przykładowy kodZałączniku C: przykładowy kod do zastosowania korzystają jednak z funkcji, które nie są obsługiwane przez Androida. Niektóre przykłady zawierają też błędy typograficzne lub korzystają z interfejsów API, które prawdopodobnie ulegną zmianie. Posługiwać się nimi należy z ostrożnością. Chociaż kod może być przydatny do zrozumienia pełnego standardu OpenSL ES, nie należy go używać w postaci domyślnej w przypadku Androida.

Treść audio

Oto niektóre z wielu sposobów łączenia treści audio w pakiety:

  • Zasoby: gdy umieścisz pliki audio w folderze res/raw/, powiązane interfejsy API Resources będą miały do nich łatwy dostęp. Nie ma jednak bezpośredniego dostępu do zasobów, więc musisz napisać kod w języku programowania Java, aby skopiować je przed użyciem.
  • Zasoby: umieszczenie plików audio w folderze assets/ powoduje, że są one bezpośrednio dostępne dla interfejsów API do zarządzania zasobami natywnej aplikacji na Androida. Więcej informacji o tych interfejsach API znajdziesz w plikach nagłówkowych android/asset_manager.handroid/asset_manager_jni.h. Przykładowy kod znajdujący się w repozytorium GitHub android-ndk używa tych interfejsów API do obsługi natywnego menedżera zasobów w połączeniu z lokalizatorem danych w plikach opisów Androida.
  • Sieć: możesz użyć lokalizatora danych URI, aby odtwarzać treści audio bezpośrednio z sieci. Pamiętaj jednak, aby zapoznać się z artykułem Zabezpieczenia i uprawnienia.
  • Lokalny system plików: identyfikator danych URI obsługuje schemat file: w przypadku plików lokalnych, o ile są one dostępne dla aplikacji. Pamiętaj, że framework zabezpieczeń Androida ogranicza dostęp do plików za pomocą mechanizmów identyfikatora użytkownika i identyfikatora grupy systemu Linux.
  • Nagranie: aplikacja może nagrywać dane audio z wejścia mikrofonu, a potem przechowywać i odtwarzać je później. Przykładowy kod korzysta z tej metody w przypadku klipu odtwarzanego.
  • Zkompilowany i połączony w ramach inline: możesz połączyć zawartość audio bezpośrednio z zasobami wspólnymi, a potem odtworzyć ją za pomocą odtwarzacza audio z lokalizatorem danych kolejki buforowej. Ta opcja najlepiej sprawdza się w przypadku krótkich klipów w formacie PCM. Ten przykładowy kod korzysta z tej techniki w klipach Hello i Android. Dane PCM zostały przekonwertowane na ciągi szesnastkowe za pomocą narzędzia bin2c (nie użyto).
  • Synteza w czasie rzeczywistym: aplikacja może syntetyzować dane PCM na bieżąco, a następnie odtwarzać je za pomocą odtwarzacza audio z lokalizatorem danych kolejki buforowej. Jest to stosunkowo zaawansowana technika, a szczegóły syntezy dźwięku wykraczają poza zakres tego artykułu.

Uwaga: ten artykuł nie dotyczy znajdowania ani tworzenia przydatnych treści audio do aplikacji. Aby znaleźć więcej informacji, możesz użyć w wyszukiwarce internetowej takich haseł jak interaktywne audio, audio do gier, projektowanie dźwięku i programowanie dźwięku.

Uwaga: Twoim obowiązkiem jest upewnić się, że możesz legalnie odtwarzać i nagrywać treści. W przypadku nagrywania treści mogą mieć zastosowanie kwestie prywatności.

Przykłady kodu

Te przykładowe aplikacje są dostępne na naszej stronie GitHub:

  • audio-echo tworzy pętlę ruchu w obie strony między wejściami i wyjściami.
  • native-audio to prosty dyktafon/odtwarzacz dźwięku.

Implementacja OpenSL ES w Android NDK różni się w pewnych aspektach od specyfikacji referencyjnej OpenSL ES 1.0.1. Te różnice są ważnym powodem, dla którego kod przykładowy skopiowany bezpośrednio ze specyfikacji referencyjnej OpenSL ES może nie działać w aplikacji na Androida.

Więcej informacji o różnicach między specyfikacją referencyjną a implementacją na Androidzie znajdziesz w artykule OpenSL ES na Androida.