Dźwięk o małym opóźnieniu sprawia, że gry są bardziej realistyczne i responsywne.
Wykonaj czynności z poniższej listy kontrolnej, aby włączyć dźwięk z niskim opóźnieniem w grze na Na urządzeniu z Androidem:
- Użyj oboju
- Żądanie w trybie wydajności „małe opóźnienie”
- Wysyłanie prośby o tryb udostępniania „Wyłączny”
- Używaj 48 000 Hz lub konwertera częstotliwości próbkowania obojowego
- Ustaw użycie na AAUDIO_USAGE_GAME
- Używanie wywołań zwrotnych danych
- Unikaj blokowania operacji w wywołaniu zwrotnym
- Popraw rozmiar bufora na „podwójny bufor”
1. Używanie interfejsu Oboe API
Interfejs API Oboe to kod w języku C++, który wywołuje AAudio na Androidzie 8.1 (poziom interfejsu API 27) lub nowszym. Na starszych wersjach Androida: Obój korzysta z technologii OpenSL ES.
Obój jest dostępny na GitHubie lub jako gotowym pliku binarnym. Obój ma też aplikację QuirksManager, która rozwiązuje problemy na konkretnych urządzeniach, dzięki czemu Twoja aplikacja jest zgodna z większą liczbą urządzeń. Jeśli nie możesz użyć Obój, użyj AAudio.
2. Żądanie w trybie niskiego opóźnienia
W przypadku obojów lub AAudio możesz żądać trybu niskiego opóźnienia. W przeciwnym razie uzyskasz wyższy .
Obój
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
AAudio
AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
3. Tryb na wyłączność
Możesz również poprosić o wyłączny dostęp do bufora MMAP. Aplikacja może nie otrzymać dostępu na wyłączność, ale jeśli tak, aplikacja zapisuje bezpośrednio w buforze, jest odczytywany przez platformę DSP, co zapewnia aplikacji najkrótszy możliwy czas oczekiwania.
Obój
builder.setSharingMode(oboe::SharingMode::Exclusive);
AAudio
AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);
4. Unikaj konwersji częstotliwości próbkowania
Używaj naturalnej częstotliwości próbkowania urządzenia. Aby to zrobić, nie podawaj parametru częstotliwość próbkowania i prawie na pewno 48 000 Hz. Jeśli podasz przykład platforma audio wysyła dane inną ścieżką, która może mieć znacznie większe opóźnienie.
Jeśli chcesz użyć innej częstotliwości próbkowania, użyj funkcji Oboe. konwersja:
builder->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium);
5. Prawidłowo zadeklaruj swój przypadek użycia
Określanie powodu, dla którego aplikacja odtwarza dźwięk, ma kluczowe znaczenie dla jego zastosowania.
z prawidłowymi ustawieniami routingu, głośności i wydajności. Gry powinny na przykład:
wskazuje wykorzystanie AAUDIO_USAGE_GAME
, aby w pełni wykorzystać czas oczekiwania
zwłaszcza przy podłączeniu do zestawu słuchawkowego Bluetooth.
Obój
builder.setUsage(oboe::Usage::Game);
AAudio
AAudioStreamBuilder_setUsage(builder, AAUDIO_USAGE_GAME);
6. Korzystanie z funkcji wywołania zwrotnego
Użycie wywołania zwrotnego dla strumienia wyjściowego. Jeśli korzystasz z blokowania zapisów i masz włączone urządzenia nieobsługującego trybu AAudio MMAP, opóźnienie może być wyżej.
Obój
builder.setDataCallback(&myCallbackObject);
AAudio
AAudioStreamBuilder_setDataCallback(builder, &my_callback_proc);
7. Unikaj blokowania w wywołaniu zwrotnym
Jeśli używasz strumienia o małym opóźnieniu, czas między wywołaniami zwrotnymi może być bardzo tylko kilka milisekund. Bardzo ważne jest, aby nie w wywołaniu zwrotnym cokolwiek, co mogłoby blokować reklamy na dłuższy czas. Jeśli wywołanie zwrotne to jeśli w dźwięku pojawiają się niedoskonałości bufora i zakłócenia.
W wywołaniu zwrotnym unikaj tych czynności:
- Przydzielanie lub zwalnianie pamięci
- I/O pliku lub sieci
- Oczekiwanie na muteks lub blokadę.
- Sen
- Obliczenia związane z intensywnym jednorazowym wykorzystaniem procesora
Wywołania zwrotne powinny przeprowadzać obliczenia w równomiernym tempie, aby zapewnić płynne odtwarzanie bez lub występują błędy.
8. Dostosuj rozmiar bufora
Gdy aplikacja otworzy strumień audio, musisz dostroić rozmiar użytego bufora pod kątem optymalnego opóźnienia. Obój automatycznie ustawia rozmiar bufora na 2 serie. Ale w przypadku AAudio, wartość domyślna jest znacznie wyższa. Użyj podwójnego buforowania, ustawiając parametr dwukrotnie większy rozmiar bufora. Rozmiar serii to maksymalne wywołanie zwrotne rozmiaru.
AAudio:
int32_t frames = AAudioStream_getFramesPerBurst() * 2;
AAudioStream_setBufferSizeInFrames(stream, frames);
Jeśli rozmiar bufora jest zbyt mały, mogą wystąpić problemy.
poniżej założeń. Liczbę błędów możesz sprawdzić, dzwoniąc
AAudioStream_getXRunCount(stream)
W razie potrzeby zwiększ rozmiar bufora.
Zobacz Dokumentacja obojów na GitHubie , gdzie znajdziesz terminologię związaną z buforem.
OpenSL ES
Jeśli korzystasz z wersji Androida starszej niż 8.1, musisz użyć polecenia OpenSL ES. Jeśli używasz Obój, możesz skonfigurować aplikację, aby ulepszyć opóźnienia. Zobacz Uzyskiwanie optymalnego czasu oczekiwania w dokumentacji GitHub.
Wyniki listy kontrolnej
Poniższa tabela zawiera Tester Oboe dane dotyczące czasu oczekiwania w obie strony (od danych wejściowych do wyjścia).
Konfiguracja | Czas oczekiwania (ms) |
---|---|
Postępuj zgodnie ze wszystkimi zaleceniami | 20 |
Tryb wydajności nie ma małego opóźnienia | 205 |
NIE WYJĄTKOWA (WSPÓLNA) | 26 |
44100 Hz (AAudio) | 160 |
44100 Hz (Oboe SRC) | 23 |
Nieużywanie wyjściowego wywołania zwrotnego (MMAP) | 21 |
Brak wyjściowego wywołania zwrotnego (nie MMAP) | 62 |
Ustawiono maksymalny rozmiar bufora | 53 |