Advanced AOSP Subsystems
4 min read

AudioFlinger

Overview

AudioFlinger is the central audio server in Android. It is a native system service (audioserver process) responsible for managing audio streams from multiple applications, mixing them together, applying effects, and sending the final output to the Audio Hardware Abstraction Layer (HAL). It acts as the gatekeeper for all audio hardware access.

AudioFlinger as the Audio Server

When an application creates an AudioTrack, it communicates via Binder to AudioFlinger. AudioFlinger manages a set of worker threads, each tied to a specific output stream provided by the Audio HAL.

The relationship can be visualized as: App (AudioTrack) -> Shared Memory -> AudioFlinger Thread -> Audio HAL -> DSP -> Speaker

AudioFlinger Threads

AudioFlinger does not process audio on its main Binder thread. Instead, it spawns dedicated playback threads based on the hardware capabilities and the type of audio being played.

MixerThread

This is the most common thread. It receives PCM data from multiple AudioTrack instances, resamples them to a common sample rate, applies volume scaling, and mixes them into a single buffer.

  • Use Case: Standard UI sounds, media playback that doesn't use offload, multiple apps playing simultaneously.

DirectOutputThread

This thread handles audio streams that bypass the software mixer. It takes a single AudioTrack and passes its data directly to the HAL.

  • Use Case: Multi-channel audio (like 5.1 surround sound) going via HDMI, or high-resolution audio (e.g., 24-bit/192kHz) where software mixing would degrade quality. Only one app can use a direct output at a time.

OffloadThread

An evolution of the DirectOutputThread, the OffloadThread is used for compressed audio (like MP3 or AAC). Instead of the app decoding the audio, the compressed bitstream is sent down to AudioFlinger, which passes it directly to the hardware DSP for decoding.

  • Use Case: Low-power audio playback (screen off music listening). The main CPU can sleep while the DSP decodes and plays the audio buffer.

Mixing and Resampling

The MixerThread relies on the AudioMixer component.

  1. Format Conversion: It converts 16-bit integer PCM or 24-bit packed PCM into floating-point format for precise mixing.
  2. Resampling: If an app supplies 44.1kHz audio, but the hardware operates at 48kHz, the AudioMixer uses a high-quality resampler (often utilizing FIR filters) to match the hardware rate.
  3. Volume & Ramping: It applies track-specific volumes and master volumes. It uses "ramping" (gradual volume changes) to prevent audible pops or clicks when streams start, stop, or change volume.

Native Code: Thread Loop

The core of an AudioFlinger playback thread is the threadLoop. This loop continuously fetches data from the shared memory buffers of active tracks, mixes them, and writes to the HAL.

// Simplified representation of frameworks/av/services/audioflinger/Threads.cpp
bool AudioFlinger::PlaybackThread::threadLoop() {
    while (!exitPending()) {
        // 1. Process configuration changes and effect updates
        processConfigEvents_l();

        // 2. Prepare tracks for mixing (check who has data)
        mMixerStatus = prepareTracks_l(&tracksToRemove);

        if (mMixerStatus == MIXER_TRACKS_READY) {
            // 3. Mix the audio using the AudioMixer
            mAudioMixer->process();
        }

        // 4. Apply post-processing effects (e.g., EQ, Virtualizer)
        effectChains.process_l();

        // 5. Write the mixed buffer to the Audio HAL
        ssize_t framesWritten = mOutput->write(mMixBuffer, mBytesToWrite);
    }
    return false;
}

Audio Effects Processing Chain

AudioFlinger supports audio effects (like Equalizer, Bass Boost, or Echo Cancellation) via EffectModule and EffectChain.

  • Insert Effects: Applied to a specific AudioTrack (e.g., an app's internal EQ).
  • Auxiliary Effects: Tracks send a portion of their signal to a shared effect bus (e.g., a shared Reverb for a game environment).
  • Post-Processing: Applied to the final mixed output before hitting the HAL (e.g., system-wide volume leveling or speaker protection algorithms).

You can inspect the active threads, mixers, and effects chains using:

adb shell dumpsys media.audio_flinger