Odtwarzanie dźwięku z niskim opóźnieniem na Androidzie

Obecnie próbuję zminimalizować opóźnienie dźwięku dla prostej aplikacji:

Mam wideo na komputerze i przesyłam dźwięk wideo przez RTP do mobilnego klienta. Z bardzo podobnym algorytmem buforowania mogę osiągnąć opóźnienie 90ms na iOS, ale straszne ±180ms na Androidzie.

Zgaduję, że różnica wynika z dobrze znanych opóźnień problemów na Androidzie.

Jednak po przeczytaniu trochę, natknąłem się na to Artykuł , który stwierdza, że:

  1. Dźwięk o niskim opóźnieniu jest dostępny od Androida 4.1/4.2 w niektórych urządzeniach.

  2. Dźwięk o niskim opóźnieniu można uzyskać za pomocą libpd, która jest czystą biblioteką danych dla Androida .

Mam 2 pytania, bezpośrednio związane z tymi 2 wypowiedziami:

  1. Gdzie mogę znaleźć więcej informacji na temat nowego dźwięku o niskim opóźnieniu w Jellybean? to wszystko, co mogę znaleźć, ale jest bardzo brakuje w konkretnych informacja . Czy zmiany powinny być dla mnie przejrzyste, czy są jakieś nowe wywołania klas/API, które powinienem implementować, aby zauważyć jakiekolwiek zmiany w mojej aplikacji? Korzystam z API AudioTrack i nie jestem nawet pewien, czy powinno czerpać korzyści z tego ulepszenia, czy powinienem szukać innego mechanizmu odtwarzania dźwięku.

  2. Mam sprawdzić użycie policji? Wydaje mi się, że to jedyna szansa na osiągnięcie niższych opóźnień, ale ponieważ zawsze myśląc o PD jako narzędziu do syntezy dźwięku, czy naprawdę nadaje się do projektu, który po prostu chwyta klatki ze strumienia sieciowego i odtwarza je? Nie robię żadnej syntezy. Czy podążam złym tropem?

Jako dodatkowa uwaga, zanim ktoś wspomni o OpenSL ES, ten artykuł jasno wyjaśnia, że nie należy oczekiwać poprawy latencji po użyciu go :

"ponieważ OpenSL ES jest natywnym API C, nie-Dalvik wątki aplikacji które wywołanie OpenSL ES nie ma żadnych kosztów związanych z Dalvikiem, takich jak śmieci pauzuje kolekcja. Nie ma jednak żadnych dodatkowych korzyści w zakresie wydajności do korzystania z OpenSL ES innych niż ten. W szczególności wykorzystanie OpenSL ES nie powoduje niższego opóźnienia dźwięku, wyższego priorytetu planowania, itd. niż to, co Platforma ogólnie zapewnia."

Author: eerock, 2013-02-13

6 answers

Aby uzyskać najniższe opóźnienie na Androidzie od wersji 4.2.2, należy wykonać następujące czynności, uporządkowane od najmniej do najbardziej oczywistych:

  1. Wybierz urządzenie, które obsługuje FEATURE_AUDIO_PRO, jeśli to możliwe, lub FEATURE_AUDIO_LOW_LATENCY, jeśli nie. ("Niskie opóźnienie" to 50ms w jedną stronę; pro to

  2. Użyj OpenSL. Dalvik GC charakteryzuje się niskim kosztem amortyzacji, ale podczas pracy zajmuje więcej czasu, niż może pozwolić na to wątek audio o niskim opóźnieniu.

  3. Przetwarzanie dźwięku w buforze Kolejka System uruchamia wywołania kolejki bufora w wątku, który ma korzystniejsze planowanie niż zwykłe wątki trybu użytkownika.

  4. Zmień rozmiar bufora na wielokrotność AudioManager.getProperty (PROPERTY_OUTPUT_FRAMES_PER_BUFFER). W przeciwnym razie oddzwanianie będzie od czasu do czasu otrzymywać dwa połączenia na raz, a nie jedno. Chyba że użycie procesora jest naprawdę lekkie, to prawdopodobnie skończy się glitching. (Na Androidzie M bardzo ważne jest, aby używać dokładnie rozmiaru bufora systemu, ze względu na błąd w kodzie obsługi bufora.)

  5. Użyj częstotliwości próbkowania dostarczonej przez AudioManager.getProperty (PROPERTY_OUTPUT_SAMPLE_RATE). W przeciwnym razie bufory przejdą przez systemowy resampler.

  6. Nigdy nie twórz syscall ani nie blokuj obiektu synchronizacji wewnątrz wywołania zwrotnego bufora. Jeśli musisz zsynchronizować, użyj konstrukcji bez blokady. Aby uzyskać najlepsze wyniki, użyj całkowicie wolnej od oczekiwania struktury, takiej jak bufor pierścieniowy z pojedynczym czytnikiem. Mnóstwo programistów to rozumie błąd i kończy się usterkami, które są nieprzewidywalne i trudne do debugowania.

  7. Używaj instrukcji wektorowych, takich jak NEON, SSE lub jakikolwiek równoważny zestaw instrukcji znajduje się na procesorze docelowym.

  8. Przetestuj i zmierz swój kod. Śledź, jak długo trwa bieg-i pamiętaj, że musisz znać najgorszą wydajność, a nie średnią, ponieważ najgorszy przypadek jest tym, co powoduje usterki. I zachowuj się konserwatywnie. Już wiesz, że jeśli zajmie to więcej czasu, aby przetworzyć twój dźwięk niż to robi, aby go odtworzyć, nigdy nie uzyskasz niskich opóźnień. Ale na Androidzie jest to jeszcze ważniejsze, ponieważ częstotliwość procesora tak bardzo się waha. Możesz użyć prawdopodobnie 60-70% procesora dla dźwięku, ale pamiętaj, że to się zmieni, gdy urządzenie stanie się cieplejsze lub chłodniejsze, lub gdy radio wifi lub LTE uruchomi się i zatrzyma, i tak dalej.

Dźwięk o niskim opóźnieniu nie jest już nową funkcją dla Androida, ale nadal wymaga zmian w sprzęcie, sterownikach, jądrze i urządzeniach ramy do ściągnięcia. Oznacza to, że istnieje wiele różnic w opóźnieniach, których można oczekiwać od różnych urządzeń, a biorąc pod uwagę, ile różnych punktów cenowych sprzedają telefony z Androidem, prawdopodobnie zawsze będą różnice. Wyszukaj FEATURE_AUDIO_PRO lub FEATURE_AUDIO_LOW_LATENCY, aby zidentyfikować urządzenia spełniające kryteria opóźnienia wymagane przez aplikację.

 62
Author: Ian Ni-Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 19:48:21

Podczas korzystania z OpenSL ES należy spełnić następujące wymagania, aby uzyskać niskie opóźnienia w Jellybean i nowszych wersjach Androida:

  • Dźwięk powinien być mono lub stereo, liniowy PCM.

  • Częstotliwość próbkowania dźwięku powinna być taka sama jak częstotliwość wyjściowa (może to nie być wymagane na niektórych urządzeniach, ponieważ FastMixer czy jest zdolne do ponownego próbkowania, jeśli sprzedawca skonfiguruje go do tego. Ale w moich testach dostałem bardzo zauważalne artefakty przy upsamplingu z 44,1 do 48 kHz w FastMixer).

  • Twój BufferQueue powinien mieć co najmniej 2 bufory. (Od tego czasu wymóg ten został złagodzony. Zobacz ten commit autorstwa Glenna Kastena. Nie jestem pewien, w której wersji Androida pojawiła się po raz pierwszy, ale zgaduję, że 4.4).

  • Nie można używać pewnych efektów (np. pogłos, wzmocnienie basu, wyrównanie, Wirtualizacja, ...).

Klasa SoundPool będzie również próbowała wykorzystać szybki AudioTrack s wewnętrznie, gdy jest to możliwe(obowiązują te same kryteria jak powyżej, z wyjątkiem części BufferQueue).

 6
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-11 14:09:03

Z linku w punkcie 1:

" dźwięk o niskim opóźnieniu

Android 4.2 poprawia obsługę odtwarzania dźwięku z niskim opóźnieniem, rozpoczynając z ulepszeń wprowadzonych w Androidzie 4.1 dla wyjścia audio opóźnienie przy użyciu interfejsów API OpenSL ES, Soundpool i tone generator. Te ulepszenia zależą od wsparcia sprzętowego-urządzenia, które oferują te funkcje audio o niskim opóźnieniu mogą reklamować swoje wsparcie dla aplikacji poprzez stała funkcji sprzętowej."

Twój cytat w pełnej formie:

"Wydajność

Ponieważ OpenSL ES jest natywnym API C, nie-Dalvik wątków aplikacji, które wywołanie OpenSL ES nie ma żadnych kosztów związanych z Dalvikiem, takich jak śmieci pauzuje kolekcja. Nie ma jednak żadnych dodatkowych korzyści w zakresie wydajności do korzystania z OpenSL ES innych niż ten. W szczególności wykorzystanie OpenSL ES nie powoduje niższego opóźnienia dźwięku, wyższego priorytetu planowania, itd. niż to, co Platforma ogólnie zapewnia. Z drugiej strony, jako Platforma Android i konkretne implementacje urządzeń nadal evolve, aplikacja OpenSL ES może oczekiwać korzyści z każdej przyszłości poprawa wydajności systemu."

Tak więc, api do komunikacji ze sterownikami, a następnie hw jest OpenSl (w taki sam sposób, jak Opengl z Grafiką). Wcześniejsze wersje Androida mają jednak złą konstrukcję w sterownikach i / lub sprzęcie. Problemy te zostały rozwiązane i poprawione w wersjach 4.1 i 4.2, więc jeśli hd ma moc, masz niskie opóźnienie przy użyciu OpenSL.

Ponownie, z tej notatki ze strony biblioteki puredata wynika, że biblioteka używa samego OpenSL, aby osiągnąć małe opóźnienie:

Obsługa małych opóźnień dla urządzeń zgodnych Najnowsza wersja Pd dla Android (stan na 28.12.2012) obsługuje dźwięk o niskim opóźnieniu dla zgodnego Urządzenia z systemem Android. Podczas aktualizacji kopii upewnij się, że pobrałeś najnowszą wersję wersja zarówno PD-for-android, jak i submodule libpd z GitHub.

W czasie pisanie, Galaxy Nexus, Nexus 4 i Nexus 10 zapewniają ścieżka o niskim opóźnieniu dla wyjścia audio. W celu osiągnięcia niskich opóźnień track, aplikacja musi korzystać z OpenSL i musi działać na prawidłowym częstotliwość próbkowania i rozmiar bufora. Parametry te zależą od urządzenia (Galaxy Nexus i Nexus 10 działają z częstotliwością 44100Hz, podczas gdy Nexus 4 działa przy 48000Hz; rozmiar bufora jest inny dla każdego urządzenia).

Jak to ma w zwyczaju, PD dla Androida papiery na wszystkie te zawiłości jak jak najwięcej, zapewnienie dostępu do nowych funkcji o niskim opóźnieniu gdy jest dostępna, pozostając wstecznie kompatybilnym z wcześniejszymi wersje Androida. Pod maską Komponenty audio Pd dla Android będzie korzystał z OpenSL na Androidzie 2.3 i nowszych, jednocześnie wycofując na Starym Audiotracku / AudioRecord API w Javie na Androida 2.2 i wcześniej.

 4
Author: AndrewBloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-21 15:33:11

Ci z Was bardziej zainteresowani problemem 10 milisekund Androida, tj. niskim opóźnieniem dźwięku na Androidzie. W Superpowered stworzyliśmy Android Audio Path Latency Explainer. Zobacz tutaj:

Http://superpowered.com/androidaudiopathlatency/#axzz3fDHsEe56

 3
Author: Patrick Vlaskovits,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-07 16:10:48

Inna baza danych opóźnień audio i używanych rozmiarów buforów:

Http://superpowered.com/latency/#table

Kod źródłowy:

Https://github.com/superpoweredSDK/SuperpoweredLatency

 2
Author: Christopher Fraser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 08:24:09
 0
Author: Mickey Tin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-19 14:19:20