Writing an OS Kernel from Scratch | Audio Subsystem — How ALSA Plays Sound
Have you ever wondered about this process: When playing a song, how does the CPU turn digital signals into vibrations from the speaker? From WAV/MP3 files to music in your headphones, there’s sampling rate, bit depth, alsa-lib, the ALSA driver, HDA controller — a chain deeper than most people imagine.
This article starts with PCM principles, explains the ALSA architecture and HDA Intel controller, giving you a complete “audio from file to headphones” map.
I. Digitizing Sound: Sampling Rate and Bit Depth
Sound is a continuous analog signal. Digitization requires two steps: Sampling and Quantization.
Analog signal (continuous)
╭──────────────────────────────╮
│ ╱╲ ╱╲ │
│ ╱╲╱╲ ╱╲ │ ╱╲ │
──╱──────────────────────────╱────→ Time
│
↓ Sampling
╭──────────────────────────────╮
│ ■ ■ ■ ■ ■ ■ ■ │ ← Sample points
────────────────────────────────→ Time
│ ← One amplitude value every T secondsKey parameters:
- Sample Rate: Number of samples per second, in Hz. CD standard is 44100Hz (44.1kHz), sufficient to reproduce 22kHz sound (Nyquist theorem: sample rate ≥ 2× max frequency)
- Bit Depth: Number of bits per sample. CD is 16-bit, Hi-Res is 24-bit. Higher bit depth = larger dynamic range (SNR = 6.02×bit + 1.76 dB)
- Channels: Mono=1, Stereo=2, Surround=6 (5.1)
PCM frame structure:
Stereo 44.1kHz 16-bit, each frame:
┌──────────┬──────────┐
│ L (16bit)│ R (16bit)│
└──────────┴──────────┘
Time domain: ────────────────────────────────→ Time
Frame N: [L0][R0] [L1][R1] [L2][R2] ...II. ALSA Architecture: From libasound to DMA
ALSA (Advanced Linux Sound Architecture) is Linux’s audio framework, divided into user space and kernel space layers:
Application (aplay / Firefox / Spotify)
│
▼
┌──────────────────────────────────┐
│ alsa-lib (libasound.so) │ ← User space
│ PCM API: snd_pcm_open/write │
│ Mixer API: snd_mixer_ │
└──────────────┬───────────────────┘
│ Write PCM ring buffer
┌─────────────┴──────────────────────┐
│ ALSA Core (snd-pcm.ko) │ ← Kernel space
│ Audio stream management, │
│ hardware parameter negotiation │
└──────────────┬───────────────────┘
│ DMA descriptors
┌─────────────┴──────────────────────┐
│ HDA Intel driver (snd-hda-intel) │ ← Hardware driver
│ Intel HD Audio Codec │
└──────────────┬───────────────────┘
│ I2S / HDA link
┌─────────────┴──────────────────────┐
│ CODEC (Realtek ALCxxx) │ ← Audio codec chip
│ DAC/ADC, amplifier, mixer │
└────────────────────────────────────┘
│
Speaker / HeadphonesIII. PCM Ring Buffer
PCM ring buffer (circular buffer):
┌──────────────────────────────────────────────┐
│ [DMA] → [audio data] → [audio data] → ... │
│ ↑ ↑ │
│ HW pointer (DMA read) App pointer (write) │
└──────────────────────────────────────────────┘
Two pointer tracking:
- HW pointer: Where the DMA controller has read data from
- App pointer: Where the application has written data to
Available space = buffer_size - (app_ptr - hw_ptr) % buffer_size
Available data = (app_ptr - hw_ptr) % buffer_sizeIV. Audio Debugging Commands
$ aplay -l # List playback devices
$ arecord -l # List capture devices
$ speaker-test -t sine -f 440 # Test speaker with 440Hz tone
$ amixer scontrols # List mixer controls
$ amixer sset Master 80% # Set master volume to 80%
$ alsamixer # Interactive mixer
# ALSA configuration
$ cat /proc/asound/cards # Sound card list
$ cat /proc/asound/pcm # PCM device list
$ cat /proc/asound/modules # Loaded ALSA modules
Comments