La version Android 4.1 a introduit des modifications de structure interne pour un chemin de sortie audio à faible latence . Il y a eu des modifications minimes de l’API du client public ou de l’API HAL. Ce document décrit la conception initiale, qui a continué à évoluer au fil du temps. Avoir une bonne compréhension de cette conception devrait aider les fournisseurs OEM et SoC d’appareils à mettre en œuvre correctement la conception sur leurs appareils et chipsets particuliers. Cet article n'est pas destiné aux développeurs d'applications.
Création de piste
Le client peut éventuellement définir le bit AUDIO_OUTPUT_FLAG_FAST
dans le paramètre audio_output_flags_t
du constructeur AudioTrack C++ ou AudioTrack::set()
. Actuellement, les seuls clients qui le font sont :
- Audio natif Android basé sur OpenSL ES ou AAudio
- android.media.SoundPool
- android.media.ToneGenerator
L'implémentation AudioTrack C++ examine la requête AUDIO_OUTPUT_FLAG_FAST
et peut éventuellement refuser la requête au niveau du client. S'il décide de transmettre la demande, il le fait en utilisant le bit TRACK_FAST
du paramètre track_flags_t
de la méthode d'usine IAudioTrack
IAudioFlinger::createTrack()
.
Le serveur audio AudioFlinger examine la requête TRACK_FAST
et peut éventuellement refuser la requête au niveau du serveur. Il informe le client si la demande a été acceptée ou non, via le bit CBLK_FAST
du bloc de contrôle de la mémoire partagée.
Les facteurs qui influencent la décision comprennent :
- Présence d'un thread mélangeur rapide pour cette sortie (voir ci-dessous)
- Suivre la fréquence d'échantillonnage
- Présence d'un thread client pour exécuter les gestionnaires de rappel pour cette piste
- Taille du tampon de piste
- Créneaux accélérés disponibles (voir ci-dessous)
Si la demande du client est acceptée, on parle alors de « procédure accélérée ». Sinon, cela s'appelle une « piste normale ».
Fils de mélangeur
Au moment où AudioFlinger crée un thread de mixage normal, il décide de créer ou non également un thread de mixage rapide. Le mixeur normal et le mixeur rapide ne sont pas associés à une piste particulière, mais plutôt à un ensemble de pistes. Il y a toujours un fil de mixage normal. Le thread mélangeur rapide, s’il existe, est subordonné au thread mélangeur normal et agit sous son contrôle.
Mélangeur rapide
Caractéristiques
Le thread de mixage rapide offre ces fonctionnalités :
- Mixage du sous-mixage du mixeur normal et jusqu'à 7 pistes rapides client
- Atténuation par piste
Fonctionnalités omises :
- Conversion de la fréquence d'échantillonnage par piste
- Effets par piste
- Effets par mixage
Période
Le mélangeur rapide s'exécute périodiquement, avec une période recommandée de deux à trois millisecondes (ms), ou une période légèrement supérieure de cinq ms si nécessaire pour la stabilité de la planification. Ce nombre a été choisi de telle sorte que, en tenant compte du pipeline tampon complet, la latence totale soit de l'ordre de 10 ms. Des valeurs plus petites sont possibles mais peuvent entraîner une consommation d'énergie accrue et des risques de problèmes en fonction de la prévisibilité de la planification du processeur. Des valeurs plus élevées sont possibles, jusqu'à 20 ms, mais entraînent une latence totale dégradée et doivent donc être évitées.
Planification
Le mélangeur rapide fonctionne avec une priorité SCHED_FIFO
élevée. Il nécessite très peu de temps CPU, mais doit s'exécuter souvent et avec une faible gigue de planification. La gigue exprime la variation du temps de cycle : c'est la différence entre le temps de cycle réel et le temps de cycle attendu. Courir trop tard entraînera des problèmes dus à un sous-fonctionnement. Courir trop tôt entraînera des problèmes dus au retrait d'une piste rapide avant que la piste n'ait fourni des données.
Blocage
Idéalement, le thread du mélangeur rapide ne se bloque jamais, sauf à HAL write()
. D'autres occurrences de blocage dans le mélangeur rapide sont considérées comme des bugs. En particulier, les mutex sont évités. Au lieu de cela, des algorithmes non bloquants (également appelés algorithmes sans verrouillage) sont utilisés. Voir Éviter l'inversion des priorités pour en savoir plus sur ce sujet.
Relation avec d'autres composants
Le mixeur rapide a peu d’interaction directe avec les clients. En particulier, il ne voit pas les opérations au niveau du classeur, mais il accède au bloc de contrôle de la mémoire partagée du client.
Le mélangeur rapide reçoit les commandes du mélangeur normal via une file d'attente d'état.
Outre l'extraction des données de piste, l'interaction avec les clients se fait via le mixeur normal.
Le récepteur principal du mélangeur rapide est le HAL audio.
Mélangeur normal
Caractéristiques
Toutes les fonctionnalités sont activées :
- Jusqu'à 32 pistes
- Atténuation par piste
- Conversion de la fréquence d'échantillonnage par piste
- Traitement des effets
Période
La période est calculée comme étant le premier multiple intégral de la période du mélangeur rapide qui est >= 20 ms.
Planification
Le mélangeur normal fonctionne avec une priorité SCHED_OTHER
élevée.
Blocage
Le mélangeur normal est autorisé à bloquer, et le fait souvent au niveau de divers mutex ainsi qu'au niveau d'un canal de blocage pour écrire son sous-mix.
Relation avec d'autres composants
Le mixeur normal interagit largement avec le monde extérieur, notamment les threads de liaison, le gestionnaire de politiques audio, le thread de mixage rapide et les pistes client.
L'évier du mixeur normal est un tuyau bloquant la piste 0 du mixeur rapide.
Drapeaux
Le bit AUDIO_OUTPUT_FLAG_FAST
est un indice. Il n'y a aucune garantie que la demande sera satisfaite.
AUDIO_OUTPUT_FLAG_FAST
est un concept au niveau client. Il n'apparaît pas sur le serveur.
TRACK_FAST
est un concept client -> serveur.