Linux Audio Architecture

Last update: 2023-01-24 01:00:34 +0800 +0800
tags: Linux | Audio
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Linux audio is a stack rather than one interchangeable API. ALSA exposes kernel sound devices and a user-space library. PulseAudio or PipeWire can then share those devices among applications, convert formats, mix streams, and apply desktop routing policy. Troubleshooting becomes deterministic when each layer is tested in signal-flow order.

ALSA: Kernel Devices and libasound #

ALSA kernel drivers register sound cards and their logical devices. User space sees card, device, and subdevice identifiers through /dev/snd, while /proc/asound exposes diagnostic state. Four interfaces matter for desktop audio:

  • PCM devices transfer sampled playback or capture frames.
  • Control devices expose mixer switches, gains, clocks, jack state, and other card-wide controls.
  • Raw MIDI and sequencer devices carry MIDI data and scheduling.
  • Timer devices provide timing facilities used by audio and MIDI clients.

A PCM frame contains one sample for every channel at one time. Before streaming, a client negotiates access mode, sample format, channel count, sample rate, period size, and buffer size. The driver and hardware move through a ring buffer while the client reads or writes frames. If playback consumes data before the client supplies it, an underrun occurs; if capture overwrites unread frames, an overrun occurs. ALSA reports both as an XRUN, commonly -EPIPE, and snd_pcm_recover() can recover supported cases.

libasound provides the snd_pcm_* and snd_ctl_* APIs plus a configuration and plugin layer. Device names have different semantics:

  • hw:0,0 addresses a hardware PCM directly and accepts only parameters that the driver supports. Another direct opener may receive EBUSY.
  • plughw:0,0 inserts libasound format, rate, or channel conversion when required.
  • default follows ALSA configuration and may resolve to a software mixer, a PulseAudio plugin, or a PipeWire plugin rather than physical hardware.

Thus a successful aplay -D hw:0,0 test proves the kernel/ALSA path but does not prove that the desktop server, its selected route, or an application’s server client is correct.

Inspect ALSA without changing configuration:

sh
cat /proc/asound/cards
aplay -l
arecord -l
aplay -L
amixer -c 0

Lowercase -l lists hardware devices; uppercase -L lists configured PCM names, including plugins. alsamixer exposes controls interactively. A muted hardware control can silence PulseAudio and PipeWire even when their software volumes are nonzero.

PulseAudio’s Server Model #

PulseAudio runs a server that owns one or more ALSA devices and accepts client streams through libpulse or compatibility plugins. Its terminology follows the server-facing direction:

  • A sink consumes playback streams and normally writes to an output device.
  • A source produces capture streams and normally reads from an input device.
  • A sink input is an application’s playback stream.
  • A source output is an application’s recording stream.
  • A monitor source captures the audio being sent to a sink.

The server negotiates client formats, resamples streams when rates differ, applies per-stream volume, mixes playback, and writes the resulting stream to ALSA. Capture follows the reverse path. Modules discover devices and provide features such as network audio, virtual devices, stream restoration, and policy integration.

PulseAudio is designed to run per user because routing, volume, Bluetooth authorization, and application streams belong to a login session. Depending on the distribution and PulseAudio version, a user systemd service/socket or libpulse autospawn starts it. A system-wide daemon is a specialized configuration with different security and device-access tradeoffs, not the desktop default.

Inspect the running server with:

sh
pactl info
pactl list short cards
pactl list short sinks
pactl list short sources
pactl list short sink-inputs
pactl list short source-outputs

pacat can play or record through the PulseAudio protocol; its historical pamon name is an alias on installations that provide it. pa-info collects a broader report for a PulseAudio bug investigation.

Discovery, Profiles, Ports, and Defaults #

A physical controller first appears as an ALSA card. PulseAudio’s device discovery then represents it as a card with profiles and ports:

  • A profile selects a card-wide mode, such as stereo output or duplex input/output. Hardware constraints can make profiles mutually exclusive.
  • A port represents a route within a profile, such as speakers, headphones, or a microphone jack.
  • A sink or source is the active streaming endpoint created by the selected profile.

Selecting the right card is insufficient if its active profile disables capture or its active port points to a disconnected route. Use the detailed outputs of pactl list cards, pactl list sinks, and pactl list sources to inspect availability, profile, port, mute, volume, and sample specification.

PulseAudio calls its default device a fallback because saved per-stream policy can override it. A newly seen stream goes to the fallback sink or source, while module-stream-restore can return a known application stream to its previous device. Set fallbacks with:

sh
pactl set-default-sink SINK_NAME
pactl set-default-source SOURCE_NAME

Existing streams may need to be moved explicitly or reopened. A desktop control panel or pavucontrol updates the same server-side concepts and is often more convenient for moving a live stream.

Latency, Resampling, and Mixing #

Latency accumulates across the complete path:

  1. The application queues frames.
  2. A server buffer and scheduling quantum hold work for mixing.
  3. A resampler or channel mixer may transform the stream.
  4. ALSA periods and the hardware buffer hold additional frames.
  5. Converters, Bluetooth codecs, or a network transport add device-specific delay.

Smaller periods and buffers reduce latency but require the application and scheduler to wake more frequently. Missing a deadline causes an XRUN or server dropout. Larger buffers improve tolerance for scheduling jitter at the cost of interactive delay. Report latency together with sample rate because a buffer of N frames contributes N / sample_rate seconds.

Mixing requires a common format and rate. PulseAudio or PipeWire therefore resamples a stream when its rate does not match the graph or hardware rate. ALSA’s plug plugin can also resample, so an unclear device path may perform conversion in more than one layer. For measurements, identify the negotiated format at the client, server, and ALSA endpoint instead of assuming the file’s sample rate reached the DAC unchanged.

Direct ALSA access can avoid a desktop server’s mixing stage, but it may take exclusive ownership and break other applications. Low latency depends on correct scheduling, period selection, and hardware behavior rather than on bypassing one named component alone.

The PipeWire Boundary #

PipeWire can replace PulseAudio’s desktop-server role without replacing ALSA. The PipeWire server uses libasound to expose ALSA devices as graph nodes; applications contribute nodes and ports, and links carry media between them. WirePlumber commonly supplies session policy: it monitors udev-backed ALSA devices, selects profiles and routes, chooses defaults, and creates links.

Compatibility services preserve existing APIs:

  • pipewire-pulse implements the PulseAudio protocol, so libpulse, pactl, and PulseAudio applications operate on PipeWire-managed objects.
  • ALSA and JACK compatibility plugins can redirect clients into PipeWire.
  • Native PipeWire clients use the PipeWire protocol directly.

Consequently, successful pactl info does not prove that the /usr/bin/pulseaudio daemon is running. Check the reported server name and the active user units:

sh
systemctl --user status pipewire.service wireplumber.service pipewire-pulse.service
systemctl --user status pulseaudio.service pulseaudio.socket
wpctl status

Only one PulseAudio-protocol server should own the session socket. On a PipeWire system, wpctl status, wpctl inspect ID, pw-dump, and pw-top show the native graph and scheduling state; pactl shows the compatibility view.

Troubleshoot in Signal-Flow Order #

Start at the lowest failing boundary and avoid changing several layers at once:

  1. Kernel discovery: Confirm the card in /proc/asound/cards, aplay -l, and arecord -l. Inspect boot-kernel messages for firmware, probe, USB, or HDMI errors.
  2. ALSA controls: Check mute, gain, and route controls with amixer or alsamixer. Test a known PCM only after stopping the server that owns it; otherwise EBUSY is expected rather than diagnostic.
  3. Server health: Determine whether PulseAudio or pipewire-pulse serves the session. Check user-unit logs and confirm that the server sees the ALSA card.
  4. Profile and route: Verify that the active profile creates the required sink or source and that its selected port is available.
  5. Stream routing: Confirm that a live sink input or source output exists, is not muted, and targets the intended device. Saved per-application routes can override the fallback.
  6. Format and timing: Compare negotiated rates, channels, buffer sizes, and XRUN counters. Use pw-top on PipeWire or verbose PulseAudio logs when dropouts correlate with scheduling load.
  7. Physical path: Test the cable, receiver, codec, microphone bias, and hardware volume after software has been shown to deliver frames to the endpoint.

Capture commands and logs before editing configuration. Device names and IDs can change across boots, so persistent rules should match stable properties rather than a transient numeric card index.

Upstream References #

Comments

Read or comment on GitHub (sign-in required to comment)