Aby zmniejszyć opóźnienie dźwięku, dostawcy mogą wdrożyć 2 kluczowe funkcje:
- FAST Mixer w AudioFlinger: wprowadzona w Androidzie 4.1 funkcja obsługuje aplikacje korzystające z Java AudioTrack i AAudio. FAST Mixer wymaga minimalnych zmian w publicznym interfejsie API klienta lub interfejsie HAL API.
- AAudio MMAP: ta funkcja wprowadzona w Androidzie 8.1 umożliwia aplikacjom natywnym osiąganie jeszcze mniejszych opóźnień dzięki AAudio. Więcej informacji znajdziesz w sekcji AAudio i MMAP.
Na tej stronie opisujemy początkową koncepcję opóźnienia dźwięku, która z czasem ulegała zmianom. Dobre zrozumienie tej konstrukcji ma kluczowe znaczenie dla producentów OEM i dostawców układów SOC, ponieważ pozwala im zapewnić prawidłowe wdrożenie na konkretnych urządzeniach i chipsetach. Ta strona nie jest przeznaczona dla deweloperów aplikacji.
Tworzenie ścieżki
Klient może opcjonalnie ustawić bit AUDIO_OUTPUT_FLAG_FAST
w parametrze audio_output_flags_t
konstruktora AudioTrack C++ lub AudioTrack::set()
. Obecnie robią to tylko te usługi:
- Natywny dźwięk na Androidzie oparty na OpenSL ES lub AAudio
android.media.SoundPool
android.media.ToneGenerator
Implementacja AudioTrack w C++ sprawdza AUDIO_OUTPUT_FLAG_FAST
żądanie i może opcjonalnie odrzucić je na poziomie klienta. Jeśli zdecyduje się przekazać żądanie dalej, zrobi to za pomocą TRACK_FAST
-bitowego parametru track_flags_t
metody fabrycznej IAudioTrack
IAudioFlinger::createTrack()
.
Serwer audio AudioFlinger sprawdza TRACK_FAST
żądanie i może opcjonalnie odrzucić je na poziomie serwera. Informuje klienta, czy żądanie zostało zaakceptowane, za pomocą bitu CBLK_FAST
bloku sterowania pamięci współdzielonej.
Czynniki, które mają wpływ na tę decyzję, to:
- Wątek szybkiego miksera dla tych danych wyjściowych (patrz poniżej)
- Śledzenie częstotliwości próbkowania
- Obecność wątku klienta do wykonywania modułów obsługi wywołań zwrotnych dla tego ścieżki
- Rozmiar bufora ścieżki
- Dostępne terminy w ramach szybkiej ścieżki (patrz poniżej)
Jeśli prośba klienta została zaakceptowana, nazywa się to szybką ścieżką. W przeciwnym razie jest to normalna ścieżka.
Wątki miksera
Gdy AudioFlinger tworzy zwykły wątek miksera, decyduje, czy utworzyć też szybki wątek miksera. Zwykły mikser i szybki mikser nie są powiązane z konkretną ścieżką, ale z zestawem ścieżek. Zawsze jest normalny wątek miksera. Wątek szybkiego miksera, jeśli istnieje, jest podporządkowany zwykłemu wątkowi miksera i działa pod jego kontrolą.
Szybki mikser
Funkcje
Wątek szybkiego miksowania zapewnia te funkcje:
- Miksowanie podmiksu normalnego miksera i maksymalnie 7 szybkich ścieżek klienta
- Tłumienie poszczególnych ścieżek
Pominięte funkcje:
- Konwersja częstotliwości próbkowania dla każdego ścieżki
- Efekty na ścieżkę
- Efekty na miks
Kropka
Szybki mikser jest uruchamiany okresowo, z zalecanym okresem 2–3 milisekund lub nieco dłuższym okresem 5 ms, jeśli jest to potrzebne do stabilności harmonogramu. Ta liczba została wybrana tak, aby uwzględniając cały potok buforowania, całkowite opóźnienie wynosiło około 10 ms. Możliwe są mniejsze wartości, ale mogą one powodować większe zużycie energii i większe prawdopodobieństwo wystąpienia problemów w zależności od przewidywalności harmonogramowania procesora. Możliwe są większe wartości (do 20 ms), ale powodują one pogorszenie całkowitego opóźnienia, dlatego należy ich unikać.
Harmonogram
Szybki mikser działa z podwyższonym priorytetem SCHED_FIFO
. Wymaga bardzo mało czasu procesora, ale musi być uruchamiany często i z niewielkim wahaniem harmonogramu.
Jitter
wyraża zmienność czasu cyklu: jest to różnica między
rzeczywistym a oczekiwanym czasem cyklu.
Zbyt późne uruchomienie powoduje problemy z powodu niedoboru danych. Uruchomienie zbyt wcześnie powoduje problemy z powodu pobierania danych z szybkiej ścieżki, zanim ścieżka dostarczy dane.
Blokowanie
W idealnej sytuacji wątek szybkiego miksera nigdy nie blokuje się poza HAL
write()
. Inne przypadki blokowania w szybkim mikserze są traktowane jako błędy. W szczególności unika się mutexów.
Zamiast tego używane są algorytmy nieblokujące (znane też jako algorytmy bez blokad).
Więcej informacji na ten temat znajdziesz w artykule Unikanie odwrócenia priorytetów.
Relacja z innymi komponentami
Szybki mikser ma niewielki bezpośredni kontakt z klientami. W szczególności nie widzi operacji na poziomie bindera, ale ma dostęp do bloku sterowania pamięcią współdzieloną klienta.
Szybki mikser otrzymuje polecenia ze zwykłego miksera za pomocą kolejki stanu.
Poza pobieraniem danych ścieżki interakcja z klientami odbywa się za pomocą zwykłego miksera.
Głównym odbiornikiem szybkiego miksera jest HAL audio.
Zwykły mikser
Funkcje
Wszystkie funkcje są włączone:
- Maksymalnie 32 ścieżki
- Tłumienie poszczególnych ścieżek
- Konwersja częstotliwości próbkowania dla każdego ścieżki
- Przetwarzanie efektów
Kropka
Okres jest obliczany jako pierwsza całkowita wielokrotność okresu szybkiego miksera, która jest ≥ 20 ms.
Harmonogram
Normalny mikser działa z podwyższonym SCHED_OTHER
priorytetem.
Blokowanie
Zwykły mikser może blokować i często to robi w przypadku różnych muteksów, a także w przypadku potoku blokującego, aby zapisać submiksy.
Relacja z innymi komponentami
Zwykły mikser intensywnie współpracuje ze światem zewnętrznym, w tym z wątkami modułu wiążącego, menedżera zasad audio, szybkiego miksera i ścieżkami klienta.
Zwykły mikser jest połączony z szybkim mikserem za pomocą blokującego potoku na ścieżce 0.
Flagi
AUDIO_OUTPUT_FLAG_FAST
bitów to wskazówka. Nie ma gwarancji, że prośba zostanie spełniona.
AUDIO_OUTPUT_FLAG_FAST
to pojęcie na poziomie klienta. Nie pojawia się na serwerze.
TRACK_FAST
to koncepcja klient –> serwer.