Android Audio-Architektur Android Audio-Stack AudioFlinger Resampling

Der Android-Audio-Stack: Warum deine Musik resampled wird

Ein tiefer Einblick in Androids Audio-Verarbeitung -- von der App zum Lautsprecher. Erfahre, warum AudioFlinger deine Musik resampled und was du dagegen tun kannst.

· 12 Min. Lesezeit

Wie Android Audio abspielt

Jeder Ton, den dein Android-Handy macht — Benachrichtigungen, Telefonate, Spieleffekte, Musik — durchläuft dieselbe Audio-Pipeline, bevor er deine Ohren erreicht. Diese Pipeline zu verstehen ist der Schlüssel um zu verstehen, warum deine sorgfältig kuratierte verlustfreie Musiksammlung möglicherweise nicht ganz so makellos klingt, wie du es erwarten würdest.

Der Standard-Android-Audiopfad sieht so aus:

App -> AudioTrack API -> AudioFlinger -> HAL (Hardware Abstraction Layer) -> Hardware (Lautsprecher, DAC, Bluetooth-Radio)

Wenn eine Musikplayer-App Sound produzieren will, erstellt sie einen AudioTrack (oder nutzt die neuere AAudio-API, die dennoch durch dasselbe System geroutet wird). Die App schreibt PCM-Audio-Samples in diesen Track — dekodierte Audiodaten bei welcher Abtastrate und Bittiefe die Quelldatei auch enthält.

Diese Samples gelangen dann in AudioFlinger, Androids zentralen Audio-Mixing- und Routing-Dienst. AudioFlinger ist der Verkehrsregler von Android-Audio. Er nimmt Audio-Streams von jeder App auf dem System, mischt sie zusammen, wendet Systemeffekte an (wie die Systemlautstärke) und leitet das Ergebnis an das korrekte Ausgabegerät weiter. Er läuft als nativer Systemdienst mit erhöhter Priorität, und jedes einzelne Audio-Sample auf deinem Gerät passiert ihn.

Unter AudioFlinger sitzt der Hardware Abstraction Layer (HAL), eine gerätespezifische Übersetzungsschicht, geschrieben vom Handyhersteller. Der HAL konvertiert AudioFlingers Ausgabe in das Format, das die tatsächliche Hardware erwartet — ob das ein I2S-Strom für den internen DAC ist, USB-Audio-Pakete für einen externen DAC oder kodiertes Bluetooth-Audio für drahtlose Kopfhörer.

Diese Architektur ist aus Systemdesign-Perspektive elegant. Jede App kann Audio abspielen, ohne sich um Hardware-Spezifika zu kümmern, mehrere Audio-Streams mischen sich nahtlos, und das System behält die Kontrolle über Routing und Lautstärke-Policy. Aber für Musikwiedergabe führt sie zu einem Problem.

Das AudioFlinger-Problem

AudioFlinger arbeitet mit einer festen Abtastrate. Auf den meisten Android-Geräten ist diese Rate entweder 44.100 Hz oder 48.000 Hz — der Gerätehersteller entscheidet bei der HAL-Konfiguration, und sie lässt sich typischerweise nicht ändern, während das System läuft. Der häufigste Standard bei modernen Handys ist 48 kHz.

Diese feste Rate existiert, weil AudioFlinger im Kern ein Mixer ist. Er muss Audio aus mehreren Quellen kombinieren — deine Musik, eine eingehende Benachrichtigung, Navigationsansagen, ein Telefonat — zu einem einzigen Ausgabestrom. Audio zu mischen erfordert, dass alle Streams dieselbe Abtastrate haben. Statt die Mixer-Rate dynamisch zu ändern, jedes Mal wenn ein neuer Stream startet (was alle anderen aktiven Streams stören würde), wählt AudioFlinger eine Rate und resampled alles, damit es passt.

Also wird jeder Audio-Stream auf dem Gerät auf die feste Rate des Mixers resampled:

  • Dein 96-kHz-Hi-Res-FLAC? Auf 48 kHz heruntergesampled.
  • Dein 44,1-kHz-CD-Rip auf einem 48-kHz-Mixer? Auf 48 kHz hochgesampled.
  • Dein 48-kHz-Podcast auf einem 48-kHz-Gerät? Geht unverändert durch — Glück gehabt.
  • Dein DSD64 konvertiert zu 176,4-kHz-PCM? Auf 48 kHz heruntergesampled.

Google hat AudioFlinger für den allgemeinen Fall entworfen, und ehrlich gesagt ist es eine vernünftige Ingenieursentscheidung für ein Consumer-Handy. Ein Gerät, das Benachrichtigungstöne abspielt, während es Spotify streamt und navigiert, braucht eine gemeinsame Mischrate. Aber es wurde nie für audiophile Wiedergabe entworfen, und die Resampling-Qualität ist zwar adäquat, aber nicht das, was man wählen würde, wenn Klangtreue das einzige Ziel wäre.

Der in AudioFlinger eingebaute Resampler hat sich über die Jahre verbessert. Frühe Android-Versionen nutzten einen minderwertigen linearen Interpolator. Moderne Versionen (Android 5.0 und später) nutzen einen Polyphasen-Sinc-Resampler, der brauchbare Ergebnisse liefert. Aber “brauchbar” und “transparent” sind nicht dasselbe — jede Resampling-Operation führt zu einem gewissen Maß an Quantisierungsrauschen und potenziellen Aliasing-Artefakten, wie gering auch immer.

Abtastraten-Verhandlung

Die Situation ist nicht völlig hoffnungslos. Android bietet Mechanismen für Apps, die Ausgabe-Abtastrate zu beeinflussen, auch wenn die Ergebnisse… inkonsistent sind.

Wenn eine App einen Audio-Stream über die AAudio-API (Androids moderne native Audio-Schnittstelle) erstellt, kann sie eine bestimmte Abtastrate anfordern. Android versucht, diese Anforderung zu erfüllen, und die App kann dann prüfen, welche Rate tatsächlich gewährt wurde. Wenn die Geräte-Hardware und der HAL die angeforderte Rate unterstützen, bekommst du möglicherweise native Wiedergabe ohne Resampling.

Android 12 und später verbesserten dies mit besserer Unterstützung für natives Abtastraten-Switching. Auf kompatiblen Geräten kann das System die HAL-Ausgaberate ändern, um dem zu entsprechen, was die App anfordert, besonders für USB-Audio-Geräte. Eine gut designte App kann potenziell bitgenaue Ausgabe bei der nativen Rate des Tracks bekommen.

Aber “ordnungsgemäß unterstützt” leistet in diesem Satz viel Arbeit. Die Erfahrung ist frustrierend inkonsistent:

  • Samsung sperrt die Abtastrate auf einen festen Wert in ihrer HAL-Implementierung. Egal was die App anfordert, die Hardware läuft immer bei 48 kHz.
  • Pixel-Geräte waren generell permissiver und lassen dich verhandeln. Aber auch hier variiert das Verhalten zwischen Hardware-Generationen.
  • OnePlus? Hängt von der Firmware-Version ab. Das ist die Realität der Android-Audio-Entwicklung.
  • Manche OEMs erlauben dynamisches Raten-Switching, aber nur für bestimmte Ausgabegeräte (USB DACs ja, Kopfhörerbuchse nein).
  • Entwickleroptionen auf manchen Geräten bieten einen “USB-Audio-Routing”-Schalter oder Abtastraten-Override, aber diese sind vor typischen Nutzern verborgen und nicht standardisiert.

Das praktische Ergebnis ist, dass sich ein App-Entwickler nicht darauf verlassen kann, eine bestimmte Abtastrate zu bekommen. Die App muss das Gerät abtasten, eine Rate anfordern, prüfen, was sie tatsächlich erhalten hat, und sich anpassen. Dieses Abtasten-Anfordern-Verifizieren-Muster ist der einzige zuverlässige Ansatz.

Der USB-DAC-Bypass

USB-Audio-Klasse-1- und -Klasse-2-Geräte bieten den vielversprechendsten Weg zu hochwertiger Audio-Ausgabe auf Android. Wenn du einen USB DAC anschließt, erstellt Androids USB-Audio-Treiber ein neues Audio-Ausgabegerät, das AudioFlinger ansteuern kann. Da USB DACs typischerweise mehrere Abtastraten unterstützen und ihre Fähigkeiten dem Host melden, ist die Chance auf native Raten-Wiedergabe besser.

Die Audiokette mit einem USB DAC sieht so aus:

App -> AAudio API -> AudioFlinger -> USB Audio HAL -> USB Audio Class Driver -> USB DAC

Beachte, dass AudioFlinger immer noch im Pfad ist. Anders als bei Desktop-Betriebssystemen — wo WASAPI Exclusive Mode unter Windows oder Hog Mode in macOS CoreAudio den System-Mixer komplett umgehen können — bietet Android keinen echten exklusiven Zugriff auf Audio-Hardware. AudioFlinger sitzt immer zwischen App und Gerät. Immer.

Allerdings kann AudioFlinger unter günstigen Umständen als Durchleitung statt als Resampler fungieren:

  1. Die App fordert die native Abtastrate des Tracks über AAudio an.
  2. AudioFlinger prüft, ob der USB Audio HAL diese Rate unterstützt.
  3. Wenn unterstützt, konfiguriert AudioFlinger seine Ausgabe auf diese Rate.
  4. Da der einzige aktive Audio-Stream mit der Mixer-Rate übereinstimmt, findet kein Resampling statt.
  5. Samples passieren AudioFlinger unverändert und erreichen den USB DAC bei der Original-Rate.

Das ist so nah an bitgenau wie Android kommt. Die Samples werden nicht mathematisch verändert, auch wenn sie technisch durch den Mixer gehen. Damit das funktioniert, darfst du auch keine System-Sounds oder andere Audio-Streams gleichzeitig aktiv haben — alles andere, das spielt, würde AudioFlinger zurück zum Mischen und potenziellen Resampling zwingen.

Die App muss erhebliche Komplexität bewältigen, damit das funktioniert: Abtasten der unterstützten Raten des USB-Geräts, Anfordern der korrekten Rate, Verifizieren der gewährten Rate und elegantes Handling von Geräte-Trennung. Die App muss auch ihr eigenes Audio-Buffer-Sizing verwalten, da USB DACs andere Latenz-Charakteristiken als das eingebaute Audio des Handys haben.

Bluetooth: Noch eine Konvertierungsschicht

Bluetooth-Audio fügt auf AudioFlinger eine völlig separate Konvertierungsstufe hinzu. Nachdem dein Audio den System-Mixer passiert hat, gelangt es in den Bluetooth-Audio-Stack, wo es in einen Bluetooth-Audio-Codec kodiert wird, bevor es drahtlos übertragen wird.

Die Kette wird zu:

App -> AudioFlinger -> Bluetooth-Codec-Encoder -> Drahtlose Übertragung -> Kopfhörer/Lautsprecher

Jeder Bluetooth-Codec ist verlustbehaftet. Ohne Ausnahme. Die verfügbare Bandbreite auf einer Bluetooth-Verbindung reicht einfach nicht für unkomprimiertes Audio bei hohen Abtastraten. Die Codecs unterscheiden sich darin, wie aggressiv sie komprimieren und welche Qualität sie innerhalb der verfügbaren Bandbreite erreichen.

SBC (Sub-Band Codec) ist die universelle Basislinie — jedes Bluetooth-Audiogerät unterstützt ihn. Er erreicht maximal etwa 345 kbps und 48 kHz. Er hat sich mit besseren Encoder-Implementierungen deutlich verbessert, aber er ist immer noch der kleinste gemeinsame Nenner.

LDAC, entwickelt von Sony und seit Android 8.0 in Android enthalten, bietet die höchste Qualität mit bis zu 990 kbps und 96 kHz. Bei bester Einstellung gilt LDAC allgemein als transparent für die meisten Inhalte — trainierte Hörer haben in kontrollierten Tests Schwierigkeiten, es vom verkabelten Original zu unterscheiden. Aber es ist immer noch verlustbehaftete Kompression.

Für einen detaillierten Vergleich aller Bluetooth-Codecs — LDAC, aptX, aptX HD, aptX Adaptive, AAC, SBC und LC3 — siehe unseren Bluetooth-Audio-Codecs-Leitfaden.

Der wichtige Punkt: Selbst wenn du AudioFlingers Resampling umgehst (durch eine native Raten-Ausgabe), re-komprimiert die Bluetooth-Kodierung danach alles. Bitgenaue Wiedergabe über Bluetooth ist physikalisch unmöglich. Das Beste, was du tun kannst, ist, dem Bluetooth-Encoder das hochwertigste Quellsignal zuzuführen und ihn die bestmögliche Kompression machen zu lassen.

Wie Echobox den Android-Audio-Stack navigiert

Wir haben Echobox von Grund auf entworfen, um mit (und um) die Einschränkungen von Androids Audio-System zu arbeiten. Unsere Drei-Schichten-Architektur — Flutter für die UI, Rust für Audio-Orchestrierung und Zig für Echtzeit-Ausgabe — gibt uns ungewöhnliche Kontrolle über das, was mit deinem Audio in jeder Phase der Pipeline passiert.

Die Architektur

Die Flutter-Schicht behandelt alles, was du siehst und womit du interagierst — den Bibliotheks-Browser, den Now-Playing-Bildschirm und die Einstellungen. Sie berührt nie direkt Audiodaten.

Die Rust-Engine sitzt in der Mitte und übernimmt die schwere Arbeit: Datei-Dekodierung (über die Symphonia-Bibliothek für Formate wie FLAC, MP3, AAC und DSD), Abtastraten-Konvertierung, Format-Normalisierung, Audio-Analyse und Zustandsverwaltung. Wir haben Rust gewählt, weil Audio-Verarbeitung sowohl korrekt als auch schnell sein muss — seine Kombination aus Speichersicherheit und Zero-Cost-Abstraktionen bedeutet, dass wir uns nicht zwischen beidem entscheiden müssen.

Die Zig-Schicht führt den Echtzeit-Audio-Callback aus — den Code, der alle ~10 Millisekunden feuert, wenn das Betriebssystem den nächsten Audio-Block anfordert. Dieser Code muss sofort mit null Allokationen und null blockierenden Operationen antworten. Wir nutzen Zig für den Callback, weil es keinen versteckten Kontrollfluss und keine versteckten Speicherallokationen garantiert — du kannst den Code lesen und genau wissen, was er zur Laufzeit tun wird. Der Zig-Callback liest vordekodierte Samples aus einem Lock-Free-Ringpuffer (gefüllt von der Rust-Engine) und wendet eine siebenstufige DSP-Kette an: ReplayGain, Vorverstärker, parametrischer EQ, Crossfeed, Lautstärke, grafischer EQ und Limiter.

Intelligentes Abtastraten-Handling

Statt Audio blind bei irgendeiner Rate zu senden und auf das Beste zu hoffen, verhandeln wir aktiv mit dem Gerät:

  1. Die native Rate des Geräts abtasten, indem ein temporärer AAudio-Stream geöffnet wird und Android die optimale Rate für das aktuelle Ausgabegerät berichten lässt.
  2. Diese Rate bei der Initialisierung des echten Wiedergabe-Streams anfordern.
  3. Die gewährte Rate verifizieren, indem zurückgelesen wird, was Android tatsächlich bereitgestellt hat — denn die gewährte Rate kann von der angeforderten abweichen.
  4. Intelligent resamplen mit einem hochwertigen Sinc-Interpolations-Resampler, wenn die Abtastrate des Tracks von der Geräterate abweicht. Dieser Resampler nutzt einen 256-Tap-FIR-Filter mit BlackmanHarris-Fenster, was deutlich besser ist als AudioFlingers eingebauter Resampler.

Der entscheidende Vorteil hier ist die Vermeidung von doppeltem Resampling. Wenn eine naive App ein 44,1-kHz-FLAC dekodiert und bei 44,1 kHz auf einem 48-kHz-Gerät ausgibt, wird AudioFlinger es mit seinem eigenen Algorithmus auf 48 kHz resamplen. Wir vermeiden das, indem wir erkennen, dass das Gerät bei 48 kHz läuft, und ein einziges sauberes, hochwertiges Resample auf 48 kHz selbst durchführen — damit AudioFlinger nichts mehr zu konvertieren hat.

Bit-Perfect-Modus

Für USB-DAC-Nutzer bietet Echobox einen Bit-Perfect-Modus, der Androids Fähigkeiten so weit wie möglich ausreizt:

  • Fordert die exakte native Abtastrate des Tracks vom DAC an.
  • Umgeht die gesamte DSP-Kette — kein EQ, keine Lautstärkeanpassung, kein ReplayGain, kein Limiter. Dekodierte Samples passieren unverändert.
  • Wenn der DAC die angeforderte Rate nicht unterstützen kann, schlägt die Wiedergabe mit einem klaren Fehler fehl, statt still zu resamplen. Das ist beabsichtigt — wenn du bitgenau angefordert hast, verdienst du es zu wissen, wenn du es nicht bekommst.

Signalweg-Transparenz

Am wichtigsten vielleicht: Echobox zeigt dir genau, was passiert. Die Signalweg-Diagnose offenbart die komplette Audiokette in Echtzeit: Quellformat und Abtastrate, ob Resampling aktiv ist und in welcher Qualität, welche DSP-Stufen aktiv sind, welche Ausgaberate das Gerät tatsächlich nutzt und welcher Bluetooth-Codec verwendet wird, falls zutreffend.

Dieses Maß an Transparenz ist selten in Musikplayer-Apps. Die meisten Player sind eine Black Box — du drückst auf Play und vertraust darauf, dass das Richtige passiert. Echobox lässt dich verifizieren.

Routenabhängiges Verhalten

Echobox klassifiziert jedes Ausgabegerät nach Routentyp — lokaler Lautsprecher, USB DAC, Bluetooth oder Netzwerk-Renderer — und passt sein Verhalten entsprechend an. Wenn Bluetooth erkannt wird, wird der Bit-Perfect-Modus automatisch deaktiviert (weil er über einen verlustbehafteten drahtlosen Codec sinnlos ist) und DSP-Verarbeitung bleibt aktiv, damit du EQ und Lautstärkeregelung nutzen kannst. Wenn ein USB DAC angeschlossen wird, wird die volle Bandbreite an Abtastraten-Verhandlung und Bit-Perfect-Optionen verfügbar.

Diese routenabhängige Politik bedeutet, dass du Einstellungen nicht jedes Mal manuell anpassen musst, wenn du zwischen Kopfhörern und Lautsprechern wechselst. Die App erkennt die Änderung und setzt intelligente Standardwerte für jeden Ausgabetyp. Für UPnP/DLNA-Streaming zu Netzwerklautsprechern fügt Echobox eine weitere Intelligenz-Ebene hinzu — Gerätefähigkeiten erkennen und bei Bedarf transkodieren. Und wenn du bewertest, was einen Musikplayer jenseits des Audio-Stacks wirklich audiophil macht, deckt unser Audiophilen-Musikplayer-Leitfaden das vollständige Bild ab. Du kannst auch die Roadmap für Plattformverfügbarkeit jenseits von Android prüfen.

Die Realität von Android-Audio

  • AudioFlinger ist der Flaschenhals. Jeder Sound auf Android passiert diesen System-Mixer, der bei einer festen Abtastrate (normalerweise 48 kHz) arbeitet. Alles Audio wird auf diese Rate resampled, bevor es die Hardware erreicht.
  • Google hat AudioFlinger für den allgemeinen Gebrauch entworfen, nicht für audiophile Wiedergabe. Das Mischen von Benachrichtigungen, Anrufen und Musik in einen Stream erfordert eine gemeinsame Abtastrate, und Resampling ist der Kompromiss. Es ist eine vernünftige Designentscheidung — nur keine, die mit uns im Sinn getroffen wurde.
  • USB DACs bieten den besten Weg zu Qualität auf Android. Sie unterstützen mehrere Abtastraten, und wenn sie korrekt angesprochen werden, kann AudioFlinger Audio ohne Resampling durchleiten.
  • Android bietet keinen echten Exklusiv-Modus. Anders als WASAPI Exclusive unter Windows oder Hog Mode unter macOS gibt es keinen Weg, AudioFlinger vollständig zu umgehen. Der Mixer ist immer im Pfad, selbst wenn er als Durchleitung fungiert.
  • Bluetooth fügt eine weitere verlustbehaftete Konvertierung obendrauf hinzu. Kein Bluetooth-Codec ist verlustfrei, und bitgenaue Wiedergabe ist über drahtlos unmöglich.
  • Echobox bewältigt die Komplexität, indem es Geräteraten abtastet, hochwertiges Resampling durchführt wenn nötig, bitgenaue USB-DAC-Ausgabe bietet und dir per Signalweg-Diagnose genau zeigt, was passiert. Unsere Rust/Zig-Architektur gibt uns Kontrolle über die Audio-Pipeline, die die meisten Apps schlicht nicht haben.
  • Das ehrliche Fazit: Auf Android erfordert es entweder einen USB DAC mit ordentlicher Treiberunterstützung oder die Akzeptanz, dass das System resamplen wird, um deine Musik ohne ungewollte Verarbeitung von der App zu deinen Ohren zu bringen. Wir haben Echobox gebaut, um dir die Werkzeuge und Transparenz zu geben, diese Realität zu navigieren — und wenn du ein Entwickler bist, der etwas Ähnliches baut, hoffen wir, dass dieser Leitfaden dir einige der Monate erspart, die wir gebraucht haben, um es herauszufinden.

Verwandte Ratgeber


Echobox ausprobieren

Erlebe, was diese Ratgeber beschreiben — präzise Wiedergabe auf Android.

Eine E-Mail pro Meilenstein. Kein Rauschen.