Progettazione per ridurre la latenza

I fornitori possono implementare due funzionalità chiave per ridurre la latenza audio:

  • FAST Mixer in AudioFlinger:introdotta in Android 4.1, questa funzionalità supporta le app che utilizzano Java AudioTrack e AAudio. Il mixer FAST comporta modifiche minime all'API client pubblica o all'API HAL.
  • AAudio MMAP:introdotta in Android 8.1, questa funzionalità consente alle app native di ottenere una latenza ancora più bassa tramite AAudio. Per saperne di più, consulta AAudio e MMAP.

Questa pagina descrive la progettazione iniziale della latenza audio, che ha continuato a evolversi nel tempo. Una solida comprensione di questo design è fondamentale per gli OEM di dispositivi e i fornitori di SoC per garantire la corretta implementazione sui loro dispositivi e chipset specifici. Questa pagina non è destinata agli sviluppatori di app.

Creazione di tracce

Il client può impostare facoltativamente il bit AUDIO_OUTPUT_FLAG_FAST nel parametro audio_output_flags_t del costruttore C++ AudioTrack o AudioTrack::set(). Al momento, gli unici clienti che lo fanno sono:

L'implementazione C++ di AudioTrack esamina la AUDIO_OUTPUT_FLAG_FAST richiesta e può facoltativamente rifiutarla a livello di client. Se decide di inoltrare la richiesta, lo fa utilizzando il bit TRACK_FAST del parametro track_flags_t del metodo factory IAudioTrack IAudioFlinger::createTrack().

Il server audio AudioFlinger esamina la richiesta TRACK_FAST e può facoltativamente rifiutarla a livello di server. Informa il client se la richiesta è stata accettata o meno, tramite il bit CBLK_FAST del blocco di controllo della memoria condivisa.

I fattori che influiscono sulla decisione includono:

  • Presenza di un thread di mixer veloce per questo output (vedi sotto)
  • Frequenza di campionamento della traccia
  • Presenza di un thread client per eseguire i gestori di callback per questa traccia
  • Dimensione del buffer di traccia
  • Slot disponibili per la procedura rapida (vedi sotto)

Se la richiesta del cliente è stata accettata, si parla di procedura rapida. In caso contrario, si parla di traccia normale.

Thread del mixer

Quando AudioFlinger crea un normale thread del mixer, decide se creare o meno anche un thread del mixer veloce. Il mixer normale e quello veloce non sono associati a una traccia specifica, ma a un insieme di tracce. Esiste sempre un thread di mixer normale. Il thread del mixer rapido, se esiste, è subordinato al thread del mixer normale e agisce sotto il suo controllo.

Fast mixer

Funzionalità

Il filo del mixer rapido offre le seguenti funzionalità:

  • Mixaggio del submix del mixer normale e di un massimo di sette tracce veloci del client
  • Attenuazione per traccia

Funzionalità omesse:

  • Conversione della frequenza di campionamento per traccia
  • Effetti per traccia
  • Per effetti di mixaggio

Punto

Il mixer veloce viene eseguito periodicamente, con un periodo consigliato di 2-3 millisecondi o un periodo leggermente superiore di 5 ms, se necessario per la stabilità della pianificazione. Questo numero è stato scelto in modo che, tenendo conto della pipeline completa del buffer, la latenza totale sia dell'ordine di 10 ms. Sono possibili valori più piccoli, ma potrebbero comportare un aumento del consumo energetico e la possibilità di problemi a seconda della prevedibilità della pianificazione della CPU. Sono possibili valori più grandi, fino a 20 ms, ma comportano una latenza totale ridotta e pertanto devono essere evitati.

Pianificazione

Il mixer veloce viene eseguito con priorità SCHED_FIFOelevata. Richiede pochissimo tempo CPU, ma deve essere eseguito spesso e con un basso jitter di pianificazione. Jitter esprime la variazione del tempo di ciclo: è la differenza tra il tempo di ciclo effettivo e il tempo di ciclo previsto. Se il programma viene eseguito troppo tardi, si verificano problemi a causa dell'underrun. L'esecuzione troppo presto comporta problemi dovuti al recupero da una traccia rapida prima che la traccia abbia fornito i dati.

Blocco

Idealmente, il thread del mixer veloce non si blocca mai, tranne che in HAL write(). Altri casi di blocco all'interno del mixer veloce sono considerati bug. In particolare, vengono evitati i mutex. Vengono invece utilizzati algoritmi non bloccanti (noti anche come algoritmi senza blocchi). Per saperne di più su questo argomento, consulta la sezione Evitare l'inversione di priorità.

Relazione con altri componenti

Il mixer veloce ha poca interazione diretta con i clienti. In particolare, non vede le operazioni a livello di binder, ma accede al blocco di controllo della memoria condivisa del client.

Il mixer rapido riceve i comandi dal mixer normale tramite una coda di stato.

A parte l'estrazione dei dati delle tracce, l'interazione con i client avviene tramite il mixer normale.

Il sink principale del mixer rapido è l'HAL audio.

Mixer normale

Funzionalità

Tutte le funzionalità sono attive:

  • Fino a 32 tracce
  • Attenuazione per traccia
  • Conversione della frequenza di campionamento per traccia
  • Elaborazione degli effetti

Punto

Il periodo viene calcolato in modo che sia il primo multiplo intero del periodo del mixer veloce che sia >= 20 ms.

Pianificazione

Il mixer normale viene eseguito con priorità SCHED_OTHERelevata.

Blocco

Il mixer normale può bloccare e spesso lo fa in vari mutex e in una pipe di blocco per scrivere il sub-mix.

Relazione con altri componenti

Il mixer normale interagisce ampiamente con il mondo esterno, inclusi i thread del binder, Audio Policy Manager, il thread del mixer rapido e le tracce client.

Il sink del mixer normale è un tubo di blocco per la traccia 0 del mixer veloce.

Bandiere

Il bit AUDIO_OUTPUT_FLAG_FAST è un suggerimento. Non è garantito che la richiesta verrà soddisfatta.

AUDIO_OUTPUT_FLAG_FAST è un concetto a livello di cliente. Non viene visualizzato nel server.

TRACK_FAST è un concetto client-server.