Audio
Android's audio server mixes every app's sound into one stream and hands it to hardware. The buffer between them is why Android audio was famously laggy, and why AAudio exists.
Audio looks like the simplest subsystem in Android: write samples, hear sound. It is actually a hard real-time problem wearing a friendly API. Every stage adds a buffer, every buffer adds latency, and the total is what a musician feels as the delay between touching a string and hearing it.
TL;DR#
- AudioFlinger is the native audio server. It mixes every app's stream into one output and routes it to the right device.
- The audio HAL is the vendor interface. It declares the buffer sizes and periods the hardware can sustain, which is why latency varies so much between phones.
- AAudio (API 26) and the fast track exist to shorten the path for low-latency use cases.
- Audio focus is the cooperative protocol that decides which app gets to make noise.
- Since Android 13, background apps that play audio need a foreground service; since Android 15 that rule is tighter still.
Mental model#
Think of a conference call bridge.
Each participant (app) sends audio into the bridge. The bridge (AudioFlinger) mixes them, applies gain, and sends one stream to the loudspeaker. The bridge cannot start sending a sentence before it has the whole sentence, so it holds a small buffer — and that buffer is delay.
The microphone path is the same bridge in reverse, with its own buffer.
Where the analogy breaks#
A conference bridge has one output. A phone has many: speaker, earpiece, wired headset, Bluetooth, USB, hearing aids. AudioFlinger maintains a routing decision per stream, and that decision can change mid-stream — which is why unplugging headphones does not stop playback, it re-routes it.
The big picture#
Text description of this diagram
A five-stage pipeline. The app writes PCM frames into a buffer shared with the audio server, using either a callback or blocking writes. AudioFlinger mixes every active track, applies volume and effects, and routes to the chosen device; a normal mixer track and a fast track take different paths. The audio HAL writes blocks to the device at the hardware's declared period. The codec converts samples to analogue and the amplifier drives the speaker or headphones. Finally the sound reaches the ear. Each stage adds buffering, and the total is the latency a musician feels.
The pipeline makes the trade explicit: fewer, smaller buffers mean lower latency but a higher risk of underrun, which is heard as a click or a stutter.
Deep dive#
The output path in detail#
An app writes audio with AudioTrack (Java/Kotlin) or AAudio (native). Both ultimately hand frames
to AudioFlinger through a shared memory buffer — not through Binder per buffer, which would be far too
slow.
AudioFlinger:
- Mixes every active track into the output bus. Mixing is a sum with per-track volume; effects are applied here too.
- Resamples if the track's sample rate differs from the output's.
- Routes to a device, chosen by policy: the stream type, the connected devices, and the user's volume settings.
- Writes to the HAL's output stream.
The HAL then hands blocks to the hardware driver, which drains them at the sample rate.1
Latency: where the milliseconds go#
The total output latency is roughly the sum of:
- the app buffer (how much audio you write ahead),
- the mixer buffer in AudioFlinger,
- the HAL buffer and the hardware period,
- plus any resampling or effects.
On a device with a well-integrated audio DSP, the last two can be small. On a device where the HAL only supports large periods, no amount of app tuning will fix it. That is why low-latency audio is a device capability question as much as a code question.
The fast track is the platform's answer: a path with fewer stages and tighter buffers, available
only when the sample rate, format and device all line up. AAudio uses it automatically when it
can.1
AAudio and Oboe#
AAudio is a native C API added in Android 8.0 (API 26) for low-latency audio. It takes a
performance mode: LOW_LATENCY asks for the fast path, POWER_SAVING asks for the opposite.
Oboe is a wrapper library that presents one API over AAudio on new devices and over OpenSL ES on
older ones. It is the recommended choice for native audio because it handles the device matrix for
you.1
The reason a native API was needed at all: AudioTrack goes through the Java framework and has
historically had more overhead and less control over buffer sizing. For games and music apps, that
overhead was the difference between playable and not.
Audio focus: the cooperative protocol#
Only one app should be the centre of attention at a time, but many apps want to make sound. Android's answer is audio focus: an app requests focus, and the system tells other apps to duck, pause or stop.
The protocol has three parts:
- Request: the app declares the kind of audio it wants (music, navigation, a short sound).
- Callback: other apps receive a focus change and must respond — pause, lower volume, or stop.
- Loss handling: focus can be transient (a phone call) or permanent (another music app started).
The important design choice is that it is cooperative. The system does not forcibly mute an app that ignores focus; it relies on apps behaving. Apps that do not are the reason you sometimes hear two songs at once.
Permissions and background playback#
Playing audio needs no permission. Recording does: RECORD_AUDIO is a dangerous runtime
permission, and since the privacy wave it is subject to the system's microphone indicator and global
toggle.
Playback from the background is a separate constraint. A music app must run a foreground service with the media-playback type to keep playing when the user leaves it; without that, the system may stop it. Android 13 tightened this, and Android 15 tightened it further for apps that start playback from the background without a valid foreground service.23
Routing and device changes#
When a headset is plugged in or a Bluetooth device connects, the audio stack does not restart the app's stream. It re-routes the output. The app can observe the change through an audio device callback and adapt — for example, pause playback when headphones are unplugged, which is both a UX and a privacy behaviour (nobody wants their music to blast from the speaker in a lift).
Effects and spatial audio#
Audio effects (equaliser, bass boost, reverb) run in the audio framework or in the HAL, depending on the device. Spatial audio is the newer addition: it can be rendered by the platform for headphones, or by the device for speakers with the right hardware support.
The architectural point is the same as everywhere in media: the platform defines the interface, and the hardware decides how much of it is real.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 1 | 1.0 |
|
| 4 | 1.6 Donut |
|
| 5 | 2.0 Eclair |
|
| 8 | 2.2 Froyo |
|
| 9 | 2.3 Gingerbread |
|
| 11 | 3.0 Honeycomb |
|
| 13 | 3.2 Honeycomb |
|
| 14 | 4.0 Ice Cream Sandwich |
|
| 16 | 4.1 Jelly Bean |
|
| 17 | 4.2 Jelly Bean |
|
| 18 | 4.3 Jelly Bean |
|
| 19 | 4.4 KitKat |
|
| 20 | 4.4W KitKat (Wear) |
|
| 21 | 5.0 Lollipop |
|
| 22 | 5.1 Lollipop |
|
| 23 | 6.0 Marshmallow |
|
| 24 | 7.0 Nougat |
|
| 26 | 8.0 Oreo |
|
| 27 | 8.1 Oreo |
|
| 28 | 9 Pie |
|
| 29 | 10 |
|
| 30 | 11 |
|
| 31 | 12 |
|
| 32 | 12L |
|
| 33 | 13 Tiramisu |
|
| 34 | 14 Upside Down Cake |
|
| 35 | 15 Vanilla Ice Cream |
|
| 36 | 16 Baklava |
|
| 37 | 17 Cinnamon Bun |
|
Under the hood#
- the mixer and router
- the AAudio implementation
- the audio HAL contract
- AudioTrack.javathe app-facing output API
Curiosity corner#
- Audio is the master clock for video. A video player follows the audio clock, not the other way round, because audio glitches are more noticeable than a dropped frame.
- 44.1 kHz is a CD inheritance. It is not a requirement of human hearing; it is a consequence of early digital recording equipment.
- Bluetooth audio adds latency that no app can remove. The codec, the radio and the headset's own buffer all contribute, which is why wireless headphones are bad for rhythm games.
Try it#
adb shell dumpsys media.audio_flinger | head -60
adb shell dumpsys audio | head -40
adb shell cmd media.audio_flinger
Example output
Output thread 0x...:
Thread name: AudioOut_1
Normal frames: 1024
Fast frames: 192
Sample rate: 48000
HAL frame count: 240The difference between Normal frames and Fast frames in the dump is a direct read on how low the
device can go: a small fast frame count is what makes a playable instrument app possible.
Check yourself#
Check yourself
What are the four stages the media framework separates?
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsAudio overviewsource.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 13 or higherdeveloper.android.comaccessed 2026-10-27↩
- docsBehavior changes: Apps targeting Android 15 or higherdeveloper.android.comaccessed 2026-10-27↩
- docsMedia framework overviewsource.android.comaccessed 2026-10-27↩
- docsManifest.permission | API referencedeveloper.android.comaccessed 2026-10-27↩