L'audio a bassa latenza rende i giochi più realistici e reattivi.
Completa il seguente elenco di controllo per attivare l'audio a bassa latenza nel tuo gioco Android
- Usa l'oboe
- Richiedere la modalità prestazioni "bassa latenza"
- Richiedi modalità di condivisione "esclusiva"
- Utilizza 48000 Hz o il convertitore della frequenza di campionamento Oboe
- Imposta l'utilizzo su AAUDIO_USAGE_GAME
- Utilizzare i callback di dati
- Evitare di bloccare le operazioni nel callback
- Regola la dimensione del buffer su "doppio buffer"
1. Utilizzare l'API Oboe
L'API Oboe è un wrapper C++ che chiama AAudio su Android 8.1 (livello API 27) o versioni successive. Nelle versioni precedenti di Android, Oboe utilizza OpenSL ES.
Oboe è disponibile su GitHub o come un programma binario predefinito. Oboe ha anche un QuirksManager che corregge problemi su dispositivi specifici, rendendo la tua app compatibile con più dispositivi. Se non puoi utilizzare Oboe, usa direttamente AAudio.
2. Richiedi modalità a bassa latenza
Richiedi la modalità a bassa latenza con Oboe o AAudio. Altrimenti, otterrai un aumento del modalità di latenza per impostazione predefinita.
Oboe
builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
AAudio
AAudioStreamBuilder_setPerformanceMode(builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
3. Richiedi modalità esclusiva
Puoi anche richiedere l'accesso esclusivo al buffer MMAP. La tua app potrebbe non ricevere esclusivo, ma se lo fa, la tua app scrive direttamente in un buffer viene letto dal DSP, che offre all'app la latenza più bassa possibile.
Oboe
builder.setSharingMode(oboe::SharingMode::Exclusive);
AAudio
AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_EXCLUSIVE);
4. Evita la conversione della frequenza di campionamento
Utilizza la frequenza di campionamento naturale del dispositivo. Puoi farlo non specificando un e la frequenza di campionamento è quasi certamente a 48.000 Hz. Se specifichi un esempio predefinita, il framework audio invia i dati su un percorso diverso che può con una latenza molto maggiore.
Se devi utilizzare una frequenza di campionamento diversa, utilizza Oboe per eseguire la frequenza di campionamento conversione:
builder->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::Medium);
5. Dichiara correttamente il tuo caso d'uso
L'indicazione del motivo per cui l'app riproduce l'audio è fondamentale affinché il sistema possa applicarla
le impostazioni corrette per routing, volume e prestazioni. Ad esempio, i giochi
indica l'utilizzo AAUDIO_USAGE_GAME
per sfruttare appieno la latenza
ottimizzazioni, in particolare se collegate ad auricolari Bluetooth.
Oboe
builder.setUsage(oboe::Usage::Game);
AAudio
AAudioStreamBuilder_setUsage(builder, AAUDIO_USAGE_GAME);
6. Utilizzare una funzione di callback
Utilizza un callback per lo stream di output. Se utilizzi il blocco delle scritture e sei attivo un dispositivo che non supporta la modalità MMAP AAudio, la latenza potrebbe essere molto in alto.
Oboe
builder.setDataCallback(&myCallbackObject);
AAudio
AAudioStreamBuilder_setDataCallback(builder, &my_callback_proc);
7. Evita di bloccare il callback
Quando utilizzi uno stream a bassa latenza, il tempo tra i callback può essere molto solo pochi millisecondi. È quindi molto importante non eseguire qualsiasi elemento nel callback che potrebbe bloccare per molto tempo. Se il callback è bloccato, l'audio del buffer presenta un underflow e glitch.
Evita di fare quanto segue in un callback:
- Allocazione o liberazione di memoria
- I/O su file o rete
- In attesa di un mutex o di una serratura
- Sonno
- Calcoli intensivi della CPU una tantum
I callback dovrebbero fare i calcoli a un ritmo uniforme per una riproduzione fluida senza glitch.
8. Ottimizza la dimensione del buffer
Una volta che l'app apre lo stream audio, devi regolare la dimensione del buffer utilizzabile per una latenza ottimale. Oboe imposta automaticamente la dimensione del buffer su due raffica. Ma con AAudio, il valore predefinito è molto più alto. Utilizza il doppio buffering impostando la dimensione del buffer al doppio della dimensione della raffica. La dimensione della serie di foto a raffica è il numero massimo di callback dimensioni.
Audio:
int32_t frames = AAudioStream_getFramesPerBurst() * 2;
AAudioStream_setBufferSizeInFrames(stream, frames);
Se la dimensione del buffer è troppo piccola, potrebbero verificarsi degli errori causati dal
inferiore. Puoi contare gli errori chiamandoli
AAudioStream_getXRunCount(stream)
. Aumenta la dimensione del buffer in base alle esigenze.
Consulta le Documentazione su oboe GitHub per una spiegazione della terminologia relativa al buffer.
OpenSL ES
Se vengono supportate versioni di Android precedenti alla 8.1, devi utilizzare OpenSL ES. Se usi Oboe, puoi configurare la tua app per migliorare la latenza. Consulta Come ottenere una latenza ottimale nella documentazione di GitHub.
Risultati dell'elenco di controllo
La tabella seguente contiene Tester Oboe misurazioni della latenza di andata e ritorno (da input a output).
Configurazione | Latenza (ms) |
---|---|
Segui tutti i consigli | 20 |
Modalità prestazioni non bassa latenza | 205 |
Non ESCLUSIVO (CONDIVISI) | 26 |
44100 Hz (audio audio) | 160 |
44100 Hz (SRC Oboe) | 23 |
Mancato utilizzo di un callback di output (MMAP) | 21 |
Mancato utilizzo di un callback di output (non MMAP) | 62 |
Dimensione del buffer impostata al massimo | 53 |