Measuring ALSA Latency on a BeagleY‑ai with Xenomai4‑EVL
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
-
Clone and checkout ALSA‑lib v1.2.14
-
Build the latency test
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
Initial Test (Period Size = 64 Frames)
When called, the test/latency.c program will attemp 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 - if the run is succesful here, then program exits, else the process continues until the -M,--max latency is reached.
Example of successful run on BeagleY-AI with seeed2micvoicec soundcard:
Scheduler set to Round Robin with priority 99...
Playback device is hw:0,0
Capture device is hw:0,0
Parameters are 44100Hz, S16_LE, 2 channels, non-blocking mode
Poll mode: yes
Loop limit is 44100 frames, minimum latency = 64, maximum latency = 64
Hardware PCM card 0 'seeed2micvoicec' device 0 subdevice 0
Its 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
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 32
period_event : 0
start_threshold : 2147483647
stop_threshold : 64
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
appl_ptr : 0
hw_ptr : 0
Hardware PCM card 0 'seeed2micvoicec' device 0 subdevice 0
Its setup is:
stream : CAPTURE
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
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 32
period_event : 0
start_threshold : 2147483647
stop_threshold : 64
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
appl_ptr : 0
hw_ptr : 0
Trying latency 64 frames, 1451.247us, 1.451247ms (689.0625Hz)
Success
Playback:
*** frames = 44192 ***
state : RUNNING
trigger_time: 8580.707455
tstamp : 0.000000
delay : 48
avail : 16
avail_max : 48
Capture:
*** frames = 44128 ***
state : RUNNING
trigger_time: 8580.707458
tstamp : 0.000000
delay : 0
avail : 0
avail_max : 32
Maximum read: 32 frames
Maximum read latency: 725.624us, 0.725624ms (1378.1250Hz)
Playback time = 8580.707455, Record time = 8580.707458, diff = -3