36 votes

Android: API sonore (déterministe, faible latence)

Je suis révision de toutes sortes de Android son API et j'aimerais savoir lequel je dois utiliser. Mon but est d'obtenir une faible latence audio ou, au moins, déterministe du comportement en matière de retard de lecture.

Nous avons eu beaucoup de problèmes et il semble que Android son API est de la merde, donc je suis en explorer les possibilités.

Le problème que nous avons est qu'il y a un retard important entre sound_out.write(sound_samples); et son réel joué par les haut-parleurs. Il est généralement autour de 300 ms. Le problème est que sur tous les appareils, c'est différent; certains n'ont pas ce problème, mais la plupart sont paralysés (cependant, CS appel a zéro latence). Le plus gros problème avec cette ridicule de retard, c'est que sur certains appareils de ce délai, une valeur aléatoire (c'est à dire qu'il n'est pas toujours 300ms).

Je suis en train de lire à propos de OpenSL ES et j'aimerais savoir si quelqu'un a de l'expérience avec elle, ou c'est la même merde, mais enveloppé dans différents package?

Je préfère avoir un accès natif, mais je n'ai pas l'esprit de Java couche d'indirection tant que je peux obtenir déterministe du comportement: soit le retard doit être constante (pour un appareil donné), ou j'aimerais avoir accès à la position de lecture actuelle au lieu d'estimation avec une marge d'erreur de ±300 ms...

EDIT:
1.5 années plus tard, j'ai essayé plusieurs téléphones android pour voir comment je peux obtenir le meilleur possible de latence pour une communication voix en temps réel. En utilisant des outils spécialisés, j'ai mesuré le délai de waveout chemin. Les meilleurs résultats ont été plus de 100 ms, la plupart des téléphones ont été dans 180ms gamme. N'importe qui ont des idées?

27voto

Ian Ni-Lewis Points 1219

SoundPool est la plus faible latence de l'interface sur la plupart des appareils, parce que la piscine est stocké dans le traitement de l'audio. Tous les autres trajets audio exiger la communication inter-processus. OpenSL est le meilleur choix si SoundPool ne pas répondre à vos besoins.

Pourquoi OpenSL? AudioTrack et OpenSL ont les mêmes latences, avec une différence importante: AudioTrack tampon rappels sont desservies en Dalvik, tandis que OpenSL rappels sont réparés dans les threads natifs. L'implémentation actuelle de Dalvik n'est pas capables de faire des rappels à très faible latence, car il est impossible de suspendre la collecte des ordures au niveau de l'audio pour les rappels. Cela signifie que la taille minimale pour AudioTrack tampons doit être supérieure à la taille minimale pour OpenSL tampons pour maintenir glitch de la lecture.

Sur la plupart des versions d'Android, cette différence entre AudioTrack et OpenSL fait aucune différence du tout. Mais avec Jellybean, Android a maintenant une faible latence chemin audio. Le temps de latence est toujours dépendante du périphérique, mais il peut être beaucoup plus faible que précédemment. Par exemple, http://code.google.com/p/music-synthesizer-for-android/ utilise 384-frame buffers sur le Galaxy Nexus pour une puissance totale de latence de moins de 30ms. Cela nécessite l'audio fil de service tampons environ une fois toutes les 8 ms, ce qui n'était pas possible sur les précédentes versions d'Android. Il n'est pas encore réalisable dans un Dalvik fil.

Cette explication suppose deux choses: d'abord, que vous demandez le plus petit possible tampons de OpenSL et de faire de votre traitement dans la mémoire tampon de rappel plutôt qu'avec un tampon d'attente. Deuxièmement, que votre appareil prend en charge la faible latence chemin. Sur la plupart des appareils actuels, vous ne verrez pas beaucoup de différence entre AudioTrack et OpenSL ES. Mais sur les périphériques qui prennent en charge Jellybean+ et à faible latence audio, OpenSL ES vous donnera le plus faible temps de latence chemin.

2voto

Drakonite Points 1260

IIRC, OpenSL est passé à travers la même interface que AudioTrack, donc au mieux, il va correspondre à AudioTrack. (FWIW, je suis actuellement à l'aide OpenSL pour "low latency" sortie)

La triste vérité est qu'il ya pas une telle chose comme une faible latence audio sur Android. Il n'y a même pas une bonne façon de marquer et/ou de filtrer les appareils basés sur la latence audio.

L'interface que vous souhaitez utiliser pour réduire le temps de latence va dépendre de ce que vous essayez de faire. Si vous voulez avoir un flux audio, vous allez être à la recherche à OpenSL ou AudioTrack.

Si vous voulez déclencher statique oneshots vous souhaiterez peut-être utiliser SoundPool. Pour statique oneshots SoundPool aura une faible latence, les échantillons sont préchargés pour le matériel. Je pense qu'il est possible de précharger les oneshots à l'aide de OpenSL ainsi, mais je n'ai pas essayé.

1voto

SomeCallMeTim Points 1803

La latence la plus faible, vous pouvez obtenir est de SoundPool. Il y a une limite à la taille d'un son, vous pouvez jouer de cette façon, mais si vous êtes sous la limite (1Mb, IIRC) c'est assez faible temps de latence. Encore, ce n'est probablement pas 40ms, cependant.

Mais il est plus rapide que ce que vous pouvez obtenir en streaming, au moins dans mon expérience.

Mise en garde: Vous pouvez voir occasionnels se bloque dans SoundPool sur les appareils Samsung. Je suis une théorie qu'il ne se produit lorsque vous accédez à la SoundPool à partir de plusieurs threads, mais je n'ai pas vérifié cela.

EDIT: OpenSL ES apparemment a une latence extrêmement ÉLEVÉE sur le Kindle Fire, tandis que SoundPool est beaucoup mieux, mais l'inverse peut être vrai sur d'autres plates-formes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X