web-dev-qa-db-fra.com

Lecture audio à faible latence sur Android

J'essaie actuellement de réduire la latence audio pour une application simple:

J'ai une vidéo sur un PC et je transmets le son de la vidéo via RTP à un client mobile. Avec un algorithme de mise en mémoire tampon très similaire, je peux atteindre 90 ms de latence sur iOS, mais un horrible ± 180 ms sur Android.

Je suppose que la différence provient des problèmes de bien connus latency sur Android.

Cependant, après avoir lu un peu autour, je suis tombé sur cet article , qui dit que:

  1. L’audio à faible latence est disponible depuis Android 4.1/4.2 sur certains appareils.

  2. L'audio à faible latence peut être obtenu à l'aide de libpd, qui est une bibliothèque Pure Data pour Android .

J'ai 2 questions, directement liées à ces 2 déclarations:

  1. Où puis-je trouver plus d'informations sur le nouvel audio à faible temps de latence dans Jellybean? Cest tout ce que je peux trouver mais il manque cruellement en informations spécifiques . Les modifications doivent-elles être transparentes pour moi ou existe-t-il de nouveaux appels de classe/API que je devrais mettre en œuvre pour que je remarque les modifications apportées à mon application? J'utilise l'API AudioTrack, et je ne suis même pas sûr si elle devrait tirer profit de cette amélioration ou si je devrais rechercher un autre mécanisme de lecture audio.

  2. Devrais-je envisager d'utiliser libpd? Il me semble que c’est la seule chance que j’ai d’atteindre des latences plus faibles, mais comme j’ai toujours pensé à PD comme un utilitaire de synthèse audio, est-il vraiment adapté à un projet qui récupère simplement des images d’un flux réseau et les rejoue? Je ne fais pas vraiment de synthèse. Est-ce que je suis sur la mauvaise piste?

Remarque supplémentaire, avant que quelqu'un ne mentionne OpenSL ES, cet article indique clairement qu'aucune amélioration de la latence ne devrait être attendue de son utilisation :

"Etant donné qu'OpenSL ES est une API C native, les threads d'application autres que Dalvik qui appellent OpenSL ES l'utilisation d'OpenSL ES autre que celle. En particulier, l'utilisation d'OpenSL ES n'entraîne pas une latence audio inférieure, une priorité de planification supérieure, , etc. par rapport à ce que la plate-forme fournit généralement. "

39
Sergio Morales

Pour obtenir la latence la plus faible sur Android à partir de la version 4.2.2, procédez comme suit, en ordre décroissant:

  1. Choisissez un périphérique prenant en charge FEATURE_AUDIO_PRO si possible ou FEATURE_AUDIO_LOW_LATENCY si ce n'est pas le cas. ("Faible latence" correspond à 50 ms dans un sens; pro est inférieur à 20 ms.)

  2. Utilisez OpenSL. Le coût amorti du GC Dalvik GC est faible, mais son exécution prend plus de temps qu’un thread audio à faible latence ne peut en permettre.

  3. Traiter l'audio dans un rappel de file d'attente. Le système exécute des rappels de file d'attente de mémoire tampon dans un thread avec une planification plus favorable que les threads normaux en mode utilisateur.

  4. Faites de la taille de votre tampon un multiple de AudioManager.getProperty (PROPERTY_OUTPUT_FRAMES_PER_BUFFER). Sinon, votre rappel recevra parfois deux appels par tranche de temps et non un. À moins que votre utilisation du processeur ne soit vraiment légère, cela finira probablement par devenir problématique. (Sur Android M, il est très important d'utiliser EXACTEMENT la taille de la mémoire tampon du système, en raison d'un bogue dans le code de gestion de la mémoire tampon.)

  5. Utilisez le taux d'échantillonnage fourni par AudioManager.getProperty (PROPERTY_OUTPUT_SAMPLE_RATE). Sinon, vos tampons font un détour par le rééchantillonneur du système.

  6. Ne jamais effectuer d'appels système ni verrouiller un objet de synchronisation à l'intérieur du rappel de tampon. Si vous devez synchroniser, utilisez une structure sans verrou. Pour de meilleurs résultats, utilisez une structure totalement exempte d'attente, telle qu'une mémoire tampon en anneau à un seul lecteur. Les charges de développeurs se trompent et se retrouvent avec des problèmes imprévisibles et difficiles à déboguer.

  7. Utilisez des instructions vectorielles telles que NEON, SSE ou quel que soit le jeu d'instructions équivalent sur votre processeur cible.

  8. Testez et mesurez votre code. Suivez le temps écoulé - et souvenez-vous que vous devez connaître les performances dans le pire des cas, et non la moyenne, car c'est le pire des cas qui est à l'origine des problèmes. Et soyez conservateur. Vous savez déjà que s'il faut plus de temps pour traiter votre audio que pour le lire, vous n'obtiendrez jamais une faible latence. Mais sur Android, cela est encore plus important, car la fréquence du processeur fluctue énormément. Vous pouvez utiliser peut-être 60 à 70% de la CPU pour l'audio, mais gardez à l'esprit que cela changera à mesure que le périphérique devient plus chaud ou plus froid, ou que les radios wifi ou LTE démarrent et s'arrêtent, etc. 

L’audio à faible latence n’est plus une nouvelle fonctionnalité pour Android, mais il nécessite toujours des modifications du matériel, des pilotes, du noyau et de la structure spécifiques au périphérique. Cela signifie que le temps de latence que vous pouvez attendre de différents appareils varie beaucoup. Compte tenu du nombre de prix proposés par les téléphones Android, il y aura probablement toujours des différences. Recherchez FEATURE_AUDIO_PRO ou FEATURE_AUDIO_LOW_LATENCY pour identifier les périphériques qui répondent aux critères de latence requis par votre application.

64
Ian Ni-Lewis

Lorsque vous utilisez OpenSL ES, vous devez remplir les conditions suivantes pour obtenir une sortie à faible latence sur Jellybean et les versions ultérieures d'Android:

  • L'audio doit être mono ou stéréo, PCM linéaire.

  • Le taux d'échantillonnage audio doit être identique au taux d'échantillonnage natif de la sortie (il se peut que cela ne soit pas nécessaire sur certains périphériques, car FastMixerest capable de ré-échantillonner si le fournisseur le configure pour le faire. Mais dans ma tests J'ai eu des artefacts très remarquables lors de la conversion de 44,1 à 48 kHz dans la variable FastMixer).

  • Votre BufferQueue devrait avoir au moins 2 tampons. (Cette exigence a depuis été assouplie. Voir ce commit par Glenn Kasten. Je ne sais pas dans quelle version Android, cette apparition pour la première fois est apparue, mais une estimation serait de 4,4).

  • Vous ne pouvez pas utiliser certains effets (par exemple, Reverb, Bass Boost, Egalisation, Virtualisation, ...).

La classe SoundPool tentera également de faire appel à AudioTracks rapide en interne si possible (les mêmes critères que ci-dessus s'appliquent, sauf pour la partie BufferQueue.).

6
Michael

À partir du lien à votre point 1:

"Audio à faible latence

Android 4.2 améliore la prise en charge de la lecture audio à faible latence à partir de des améliorations apportées à la version Android 4.1 pour la sortie audio temps de latence avec OpenSL ES, Soundpool et les API du générateur de sons. Celles-ci les améliorations dépendent du support matériel - les périphériques qui en offrent Les fonctionnalités audio à faible latence peuvent annoncer leur soutien aux applications via une constante de fonctionnalité matérielle. "

Votre citation en forme complète:

"Performance

Comme OpenSL ES est une API C native, des threads d’application autres que Dalvik qui Appelez OpenSL ES sans frais généraux liés à Dalvik, tels que garbage pauses de collecte. Cependant, il n'y a aucun avantage de performance supplémentaire l'utilisation d'OpenSL ES autre que celle-ci. En particulier, utilisez OpenSL ES n'entraîne pas une latence audio inférieure, ni une priorité de planification plus élevée, etc. que ce que la plate-forme fournit généralement. Par contre, comme la plate-forme Android et les implémentations de périphériques spécifiques continuent à évoluer, une application OpenSL ES peut espérer tirer parti de tout avenir amélioration des performances du système. "

Ainsi, l’API pour communiquer avec les pilotes et ensuite hw est OpenSl (comme Opengl le fait avec les graphiques). Les versions antérieures d’Android ont un mauvais design en termes de pilotes et/ou d’hw. Ces problèmes ont été résolus et corrigés avec les versions 4.1 et 4.2. Par conséquent, si le disque dur est alimenté, vous obtenez une faible latence avec OpenSL.

Là encore, il ressort clairement de cette note du site Web de la bibliothèque puredata que la bibliothèque utilise OpenSL pour atteindre un faible temps de latence:

Prise en charge à faible temps de latence pour les périphériques compatibles La dernière version de Pd pour Android (à la date du 12/28/2012) prend en charge l'audio à faible latence pour se conformer Appareils Android. Lors de la mise à jour de votre copie, assurez-vous de tirer le dernier version de pd-for-Android et du sous-module libpd de GitHub.

Au moment de la rédaction de ce document, Galaxy Nexus, Nexus 4 et Nexus 10 fournissent un piste à faible latence pour la sortie audio. Afin de frapper la faible latence suivre, une application doit utiliser OpenSL, et elle doit fonctionner à la bonne taux d'échantillonnage et taille de la mémoire tampon. Ces paramètres dépendent de l'appareil (Galaxy Nexus et Nexus 10 fonctionnent à 44100Hz, tandis que Nexus 4 fonctionne À 48000Hz; la taille de la mémoire tampon est différente pour chaque appareil).

Comme à son habitude, Pd pour Android papiers sur toutes ces complexités comme dans la mesure du possible, en donnant accès aux nouvelles fonctionnalités à faible temps de latence lorsque disponible tout en restant compatible avec les versions antérieures versions d'Android. Sous le capot, les composants audio de Pd pour Android utilisera OpenSL sur Android 2.3 et versions ultérieures, tout en se repliant sur l'ancienne API AudioTrack/AudioRecord en Java sous Android 2.2 et plus tôt.

4
AndrewBloom

Ceux d’entre vous plus intéressés par le problème 10 millisecondes d’Android, c’est-à-dire l’audio à faible latence sous Android Chez Superpowered, nous avons créé l’Explainer de latence du chemin audio Android. S'il vous plaît voir ici:

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

3
Patrick Vlaskovits

Une autre base de données de latences audio et de tailles de mémoire tampon utilisées: 

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

Code source:

https://github.com/superpoweredSDK/SuperpoweredLatency

2
Christopher Fraser

Il existe une nouvelle bibliothèque C++ Oboe qui aide à réduire la latence audio. Je l'ai utilisé dans mes projets et cela fonctionne bien . Il a ces fonctionnalités qui aident à réduire la latence audio:

  • Réglage automatique de la latence
  • Choisit l'API audio (OpenSL ES sur API 16+ ou AAudio sur API 27+)
0
Wrobel

Application permettant de mesurer sampleRate et bufferSize: https://code.google.com/p/high-performance-audio/source/checkout et http://audiobuffersize.appspot.com/ DB de résultats

0
Mickey Tin