Introduction
Low‑latency audio processing is critical for embedded systems that require real‑time performance, such as voice interfaces, digital signal processing (DSP), and interactive media applications. In this post, we demonstrate how to compile and test the Advanced Linux Sound Architecture (ALSA) library on a BeagleY‑ai running a Xenomai4‑EVL 6.6.69 kernel, and analyze the latency characteristics using the provided ALSA latency test.
Background
- Platform: BeagleY‑ai development board
- Kernel: Xenomai4‑EVL 6.6.69 Integrating Xenomai 4 on BeagleY-AI: Hard Real-Time Linux
- Sound Card: ReSpeaker 2-Mics Pi HAT v2 Porting ReSpeaker 2-Mics Pi HAT v2 to BeagleY-AI
- ALSA version: Building from source at v1.2.14 (upgrading from the distribution package 1.2.8)
- Realtime scheduler: Round Robin (RR) at high priority to minimize scheduling jitter
Real‑time extensions like Xenomai’s EVL mode allow latency‑critical tasks to bypass much of the Linux scheduler’s unpredictability. ALSA’s test suite (alsa-lib/test/latency) can then measure round‑trip latency in frames and microseconds.
Environment Setup
-
Update and install prerequisites
Terminal window sudo apt updatesudo apt install automake libtool git build-essential -
Clone and checkout ALSA‑lib v1.2.14
Terminal window git clone https://github.com/alsa-project/alsa-lib.gitcd alsa-libgit checkout v1.2.14 -b v1.2.14./gitcompile -
Build the latency test
Terminal window cd alsa-lib/testmake latency
Ensure that the EVL kernel module is loaded and that your audio device (hw:0,0) is available.
Running the Latency Test
We invoke the test with the following parameters:
- Playback and capture targets:
hw:0,0 - Sample rate: 44.1 kHz
- Buffer size: 64 frames
- Period size: 64 frames (first run), then 32 frames (second run)
- Mode: Polling, non-blocking
- Scheduler: Round Robin at priority 99
sudo ./latency -P hw:0,0 -C hw:0,0 -r 44100 -m 64 -M 64 -p -s 1Initial Test (Period Size = 64 Frames)
When called, the test/latency.c program will attempt to set period/buffer sizes based on the latency entered, starting from -m,--min option (or the default minimum latency = 64 if not specified). If the run succeeds without errors with that setting, the program exits; otherwise, the latency is increased, and the run repeated.
Example of successful run on BeagleY-AI with seeed2micvoicec soundcard:
Scheduler set to Round Robin with priority 99...Playback device is hw:0,0Capture device is hw:0,0Parameters are 44100Hz, S16_LE, 2 channels, non-blocking modePoll mode: yesLoop limit is 44100 frames, minimum latency = 64, maximum latency = 64Hardware PCM card 0 'seeed2micvoicec' device 0 subdevice 0Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 44100 exact rate : 44100 (44100/1) msbits : 16 buffer_size : 64 period_size : 32 period_time : 725 ...Trying latency 64 frames, 1451.247us, 1.451247ms (689.0625Hz)SuccessPlayback:*** frames = 44192 *** state : RUNNING trigger_time: 8580.707455 tstamp : 0.000000 delay : 48 avail : 16 avail_max : 48Capture:*** frames = 44128 *** state : RUNNING trigger_time: 8580.707458 tstamp : 0.000000 delay : 0 avail : 0 avail_max : 32Maximum read: 32 framesMaximum read latency: 725.624us, 0.725624ms (1378.1250Hz)Playback time = 8580.707455, Record time = 8580.707458, diff = -3Note
The resulting round-trip latency is highly deterministic thanks to the Xenomai EVL kernel.