wake-up-neo.com

Audio-Wiedergabe mit geringer Latenz unter Android

Ich versuche derzeit, die Audio-Latenz für eine einfache Anwendung zu minimieren:

Ich habe ein Video auf einem PC und übertrage das Audio des Videos über RTP an einen mobilen Client. Mit einem sehr ähnlichen Pufferalgorithmus kann ich unter iOS eine Latenz von 90 ms erreichen, unter Android jedoch schreckliche ± 180 ms.

Ich vermute, der Unterschied ergibt sich aus den bekannten Latenz Problemen auf Android.

Jedoch, nachdem ich ein bisschen herumgelesen hatte, bin ich auf diesen Artikel gestoßen , der besagt, dass:

  1. Audio mit geringer Latenz ist seit Android 4.1/4.2 auf bestimmten Geräten verfügbar.

  2. Audio mit geringer Latenz kann mit libpd, der Pure Data-Bibliothek für Android , erstellt werden.

Ich habe zwei Fragen, die in direktem Zusammenhang mit diesen beiden Aussagen stehen:

  1. Wo finde ich weitere Informationen zum neuen Audio mit niedriger Latenz in Jellybean? Das ist alles, was ich finden kann, aber es fehlt schmerzlich an spezifischen Informationen . Sollten die Änderungen für mich transparent sein, oder gibt es einige neue Klassen-/API-Aufrufe, die ich implementieren sollte, damit ich Änderungen in meiner Anwendung bemerke? Ich verwende die AudioTrack-API und bin mir nicht einmal sicher, ob sie von dieser Verbesserung profitieren sollte oder ob ich nach einem anderen Mechanismus für die Audiowiedergabe suchen sollte.

  2. Sollte ich mich mit libpd befassen? Es scheint mir, dass dies die einzige Chance ist, niedrigere Latenzen zu erreichen, aber da ich PD immer als Audiosynthese-Dienstprogramm angesehen habe, ist es wirklich für ein Projekt geeignet, das nur Frames von einem erfasst Netzwerk-Stream und spielt sie wieder? Ich synthetisiere nicht wirklich. Folge ich der falschen Spur?

Als zusätzliche Anmerkung, bevor jemand OpenSL ES erwähnt, macht dieser Artikel deutlich, dass keine Verbesserungen der Latenz zu erwarten sind :

"Da OpenSL ES eine native C-API ist, haben Nicht-Dalvik-Anwendungsthreads, die OpenSL ES aufrufen, keinen Dalvik-bezogenen Overhead, z. B. Speicherbereinigungspausen. Die Verwendung von OpenSL ES bietet jedoch keinen zusätzlichen Leistungsvorteil als Dies. Insbesondere führt die Verwendung von OpenSL ES nicht zu einer geringeren Audio-Latenz, einer höheren Planungspriorität usw., als dies die Plattform im Allgemeinen bietet. "

39
Sergio Morales

Für die niedrigste Latenzzeit auf Android ab Version 4.2.2 sollten Sie die folgenden Schritte ausführen, und zwar vom wenigsten zum offensichtlichsten:

  1. Wählen Sie ein Gerät aus, das FEATURE_AUDIO_PRO unterstützt, oder FEATURE_AUDIO_LOW_LATENCY, falls dies nicht möglich ist. ("Niedrige Latenz" beträgt 50 ms für eine Strecke; pro ist eine <20 ms-Rundfahrt.)

  2. Verwenden Sie OpenSL. Der Dalvik-GC hat geringe Amortisationskosten, aber wenn er ausgeführt wird, dauert dies mehr Zeit, als ein Audiothread mit niedriger Latenzzeit zulässt.

  3. Audio in einem Pufferwarteschlangen-Callback verarbeiten. Das System führt Pufferwarteschlangen-Callbacks in einem Thread aus, der eine günstigere Planung als normale Threads im Benutzermodus aufweist.

  4. Machen Sie Ihre Puffergröße ein Vielfaches von AudioManager.getProperty (PROPERTY_OUTPUT_FRAMES_PER_BUFFER). Andernfalls erhält Ihr Rückruf gelegentlich zwei Anrufe pro Mal und nicht einen. Wenn Ihre CPU-Auslastung nicht wirklich gering ist, führt dies wahrscheinlich zu Störungen. (Bei Android M ist es sehr wichtig, EXACTLY die Systempuffergröße zu verwenden, da ein Fehler im Buffer-Handling-Code vorliegt.)

  5. Verwenden Sie die von AudioManager.getProperty (PROPERTY_OUTPUT_SAMPLE_RATE) bereitgestellte Abtastrate. Ansonsten machen Ihre Puffer einen Umweg durch den System-Resampler.

  6. Machen Sie niemals einen Syscall oder sperren Sie ein Synchronisationsobjekt im Puffer-Rückruf. Wenn Sie synchronisieren müssen, verwenden Sie eine schlossfreie Struktur. Um optimale Ergebnisse zu erzielen, sollten Sie eine vollständig wartungsfreie Struktur verwenden, z. B. einen Ringpuffer mit einem einzelnen Schreibgerät und nur einem Schreiber. Viele Entwickler haben das falsch verstanden und enden mit unvorhersehbaren Störungen, die schwer zu debuggen sind.

  7. Verwenden Sie Vektoranweisungen wie NEON, SSE oder den entsprechenden Befehlssatz des Zielprozessors.

  8. Testen und messen Sie Ihren Code. Verfolgen Sie, wie lange es dauert, um zu laufen - und denken Sie daran, dass Sie die Leistung des schlimmsten Falls kennen sollten, nicht den Durchschnitt, denn der schlimmste Fall ist der Grund für die Störungen. Und sei vorsichtig. Sie wissen bereits, dass Sie, wenn die Verarbeitung Ihrer Audiodaten länger dauert als die Wiedergabe, nie eine niedrige Latenz haben. Bei Android ist dies jedoch noch wichtiger, da die CPU-Frequenz so stark schwankt. Sie können vielleicht 60-70% der CPU für Audio verwenden. Bedenken Sie jedoch, dass sich dies ändert, wenn das Gerät heißer oder kühler wird oder wenn das WLAN oder die LTE - Radios starten und stoppen usw. 

Audio mit niedriger Latenz ist keine neue Funktion für Android mehr, erfordert jedoch immer noch gerätespezifische Änderungen in Hardware, Treibern, Kernel und Framework, um sich durchzusetzen. Dies bedeutet, dass die Latenzzeit, die Sie von verschiedenen Geräten erwarten können, sehr unterschiedlich ist. Angesichts der unterschiedlichen Preispunkte, auf denen Android-Handys verkauft werden, wird es wahrscheinlich immer Unterschiede geben. Suchen Sie nach FEATURE_AUDIO_PRO oder FEATURE_AUDIO_LOW_LATENCY, um Geräte zu identifizieren, die die von Ihrer App benötigten Latenzkriterien erfüllen.

64
Ian Ni-Lewis

Wenn Sie OpenSL ES verwenden, sollten Sie die folgenden Voraussetzungen erfüllen, um bei Jellybean und späteren Versionen von Android eine niedrige Latenzzeit zu erhalten:

  • Das Audio sollte mono oder stereo sein, lineares PCM.

  • Die Audio-Samplerate sollte dieselbe Sample-Rate wie die native Rate der Ausgabe sein (dies ist möglicherweise auf einigen Geräten nicht unbedingt erforderlich, da FastMixeris in der Lage ist, das Resampling erneut durchzuführen, wenn der Hersteller dies konfiguriert In meinen Tests bekam ich beim Upsampling von 44,1 auf 48 kHz in FastMixer) sehr wahrnehmbare Artefakte.

  • Ihr BufferQueue sollte mindestens 2 Puffer haben. (Diese Anforderung wurde seitdem gelockert. Siehe dieses Commit von Glenn Kasten. Ich bin nicht sicher, in welcher Android-Version diese zuerst erschien, aber eine Vermutung wäre 4.4).

  • Sie können bestimmte Effekte nicht verwenden (z. B. Reverb, Bass Boost, Equalization, Virtualization, ...).

Die SoundPool-Klasse versucht außerdem, intern möglichst schnell AudioTracks zu verwenden (es gelten dieselben Kriterien wie oben, mit Ausnahme des Teils BufferQueue).

6
Michael

Über den Link an Ihrem Punkt 1:

"Audio mit niedriger Latenz

Android 4.2 verbessert die Unterstützung für die Audiowiedergabe mit niedriger Latenz, beginnend mit von den Verbesserungen in Android 4.1 für die Audioausgabe Latenz mit OpenSL ES, Soundpool und Klangerzeuger-APIs. Diese Verbesserungen hängen von der Hardwareunterstützung ab - Geräte, die diese bieten Audiofunktionen mit niedriger Latenzzeit können Apps durch .__ ihre Unterstützung werben. eine Hardware-Feature-Konstante. "

Ihr Zitat in vollständiger Form:

"Performance

Da es sich bei OpenSL ES um eine native C-API handelt, verwenden Threads, die keine. call OpenSL ES hat keinen mit Dalvik zusammenhängenden Aufwand wie Müll Sammlungspausen. Es gibt jedoch keinen zusätzlichen Leistungsvorteil auf die Verwendung von OpenSL ES anders. Insbesondere die Verwendung von OpenSL ES führt nicht zu einer niedrigeren Audio-Latenz, höherer Planungspriorität, usw. als das, was die Plattform im Allgemeinen bietet. Andererseits als Die Android-Plattform und bestimmte Geräteimplementierungen laufen weiterhin auf entwickeln, kann eine OpenSL ES-Anwendung von jeder Zukunft profitieren Verbesserungen der Systemleistung. "

Die API, die mit Treibern kommuniziert, ist dann OpenSl (so wie Opengl mit Grafik arbeitet). Die früheren Versionen von Android haben jedoch ein schlechtes Design in Treibern und/oder hw. Diese Probleme wurden mit den Versionen 4.1 und 4.2 behoben und korrigiert. Wenn also die HD-Festplatte die Leistung hat, wird mit OpenSL eine geringe Latenz erzielt.

Aus diesem Hinweis auf der Website der Puredata-Bibliothek wird deutlich, dass die Bibliothek OpenSL selbst verwendet, um eine niedrige Latenzzeit zu erreichen:

Niedrige Latenzunterstützung für kompatible Geräte Die neueste Version von Pd für Android (Stand 28.12.2012) unterstützt Audio mit niedriger Latenz für kompatible Android-Geräte. Stellen Sie beim Aktualisieren der Kopie sicher, dass Sie das neueste Version von sowohl pd-for-Android als auch das libpd-Modul von GitHub.

Zum Zeitpunkt des Schreibens liefern Galaxy Nexus, Nexus 4 und Nexus 10 ein Track mit niedriger Latenz für die Audioausgabe. Um die niedrige Latenzzeit zu erreichen Verfolgen, eine App muss OpenSL verwenden, und sie muss mit der korrekten .__ funktionieren. Abtastrate und Puffergröße. Diese Parameter sind geräteabhängig (Galaxy Nexus und Nexus 10 arbeiten bei 44100 Hz, während Nexus 4 bei 48000 Hz arbeitet; die Puffergröße ist für jedes Gerät unterschiedlich).

Wie üblich schreibt Pd für Android alle diese Komplexitäten als Dies ermöglicht den Zugriff auf die neuen Funktionen mit niedriger Latenzzeit wenn verfügbar, dabei rückwärtskompatibel mit früheren Versionen von Android. Unter der Haube werden die Audio-Komponenten von Pd für Android wird OpenSL unter Android 2.3 und höher verwenden und fällt dabei zurück auf der alten AudioTrack/AudioRecord-API in Java unter Android 2.2 und vorhin.

4
AndrewBloom

Diejenigen von Ihnen, die sich mehr für das 10-Millisekunden-Problem von Android interessieren, dh Audio mit niedriger Latenz auf Android. Wir bei Superpowered haben den Android Audio Path Latency Explainer erstellt. Bitte sehen Sie hier:

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

3

Eine weitere Datenbank mit den verwendeten Audio-Latenzen und Puffergrößen: 

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

Quellcode:

https://github.com/superpoweredSDK/SuperpoweredLatency

2

Es gibt eine neue C++ - Bibliothek Oboe , die dazu beiträgt, die Audio-Latenz zu reduzieren. Ich habe es in meinen Projekten verwendet und es funktioniert gut ... __ Es verfügt über diese Funktionen, die dazu beitragen, die Audio-Latenz zu reduzieren:

  • Automatische Latenzabstimmung
  • Wählt die Audio-API (OpenSL ES auf API 16+ oder AAudio auf API 27+)
0
Wrobel

Anwendung zum Messen von sampleRate und bufferSize: https://code.google.com/p/high-performance-audio/source/checkout und http://audiobuffersize.appspot.com/ DB der Ergebnisse

0
Mickey Tin