Overview
AudioTrack is the primary Java/C++ API in Android for playing streaming audio. Unlike MediaPlayer, which handles the entire decoding pipeline, AudioTrack operates purely on raw, uncompressed Pulse Code Modulation (PCM) data or compressed audio formats passed directly for hardware offloading. It sits at the top of the audio framework stack, interfacing directly with the AudioFlinger system service.
AudioTrack API: Creating and Writing PCM Data
To use AudioTrack, an application must specify the audio characteristics, allocate an internal buffer, and then push PCM data into that buffer.
Initialization
Initialization requires defining the stream type, sample rate, channel configuration, and audio format (typically 16-bit PCM or Float).
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioTrack audioTrack = new AudioTrack.Builder()
.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build())
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(audioFormat)
.setSampleRate(sampleRate)
.setChannelMask(channelConfig)
.build())
.setBufferSizeInBytes(minBufferSize * 2)
.setTransferMode(AudioTrack.MODE_STREAM)
.build();
audioTrack.play();
Writing Data
In MODE_STREAM, the application continuously writes to the track in a loop. This is ideal for streaming media or synthesized audio.
short[] audioData = getNextAudioFrame();
int bytesWritten = audioTrack.write(audioData, 0, audioData.length);
In MODE_STATIC, the entire audio buffer is written once before playback begins, which is useful for short sound effects with low latency requirements.
Audio Session and Attributes
Android manages audio routing and concurrency using AudioAttributes and Audio Sessions.
- AudioAttributes: Replaced the legacy
streamType(likeSTREAM_MUSIC). They describe the why (usage) and what (content type) of the audio. TheAudioPolicyManageruses these attributes to determine routing (e.g., routingUSAGE_ALARMto the device speaker even if headphones are plugged in). - Audio Session ID: A unique identifier grouping audio streams for applying effects. If you want to apply an
Equalizerto a specificAudioTrack, you attach the effect to the track's Session ID.
Shared Memory Ring Buffer with AudioFlinger
The true power of AudioTrack lies in its IPC (Inter-Process Communication) mechanism. Writing audio data across process boundaries via standard Binder calls for every frame would introduce unacceptable latency and CPU overhead.
Instead, Android uses a lockless shared memory ring buffer (often referred to as cblk or control block).
- Allocation: When
AudioTrackis created,AudioFlingerallocates a chunk of shared memory (ashmem). - Mapping: Both the app process and the
AudioFlingerprocess map this memory into their address spaces. - Producer/Consumer:
- The App (
AudioTrack) is the Producer. It writes PCM data into the ring buffer and updates the write pointer in the control block. AudioFlingeris the Consumer. Its mixing thread reads from the buffer, updates the read pointer, and mixes it with other active tracks.
- The App (
- Synchronization: Futexes (fast userspace mutexes) are used to block the app if the buffer is full, or block
AudioFlingerif the buffer is empty (an underrun).
AudioTrack State Machine
Internally, AudioTrack maintains a strict state machine to manage the native resources.
- STATE_UNINITIALIZED: Creation failed or resources released.
- STATE_INITIALIZED: Buffer allocated, ready for playback.
- PLAYSTATE_PLAYING: AudioFlinger is actively consuming data.
- PLAYSTATE_PAUSED: Consumption stopped, buffer contents preserved.
- PLAYSTATE_STOPPED: Playback halted, buffer pointers reset.
To debug active AudioTrack instances across the system, you can dump the media.metrics or audioflinger services:
adb shell dumpsys media.audio_flinger
This command lists all active clients, their session IDs, formats, and buffer underrun statistics.