What happened?
On Shairport Sync 5.2.1 in AirPlay 2 mode, changing audio_backend_latency_offset_in_seconds did not reliably produce the requested timing change for buffered 48 kHz AAC streams.
I tested offsets of -0.250 and +0.250 seconds. I expected these to shift the RTP anchor by -12,000 and +12,000 frames respectively at 48,000 frames/sec.
The apparent cause is in handle_setrateanchori():
int32_t added_latency =
(int32_t)(config.audio_backend_latency_offset * conn->input_rate);
For buffered stream type 103, SETRATEANCHORI can arrive before the first encoded audio block. At that point conn->input_rate has not necessarily been established by prepare_decoding_chain().
Observed results before the fix:
-
In one session conn->input_rate was still zero, so the configured offset produced no RTP-anchor adjustment.
-
In another 48 kHz session it contained a stale 44,100 value, producing 11,025 frames for 250 ms instead of 12,000.
-
The first audio block later changed conn->input_rate to 48,000, after the
anchor had already been processed.
Steps to reproduce:
- Build upstream 5.2.1 with AirPlay 2 and ALSA.
- Enable diagnostic verbosity 2.
- Play a buffered AAC/F24/48 kHz AirPlay 2 stream from an Apple TV.
- Set audio_backend_latency_offset_in_seconds to -0.250, then +0.250, restarting Shairport Sync between tests.
- Observe that SETRATEANCHORI is handled before the log showing conn->input_rate being set to 48,000.
I tested a fix that reads audioFormatIndex during buffered stream SETUP, maps it to the initial SSRC format, and sets conn->input_rate before SETRATEANCHORI is received. The actual packet format remains authoritative and can update the rate later.
With that change, the same tests consistently produced the expected ±12,000 frame adjustments.
Tested patch and commit:
prhodey@30812cd
Comparison against upstream 5.2.1:
prhodey/shairport-sync@5.2.1...multiroom-5.2.2
Relevant log output
Unpatched 5.2.1 — SETRATEANCHORI precedes discovery of the 48 kHz rate:
22:49:51 "rtsp.c:1411" Connection 1: SETRATEANCHORI ...
22:49:51 "rtsp.c:1473" Connection 1: SETRATEANCHORI Start playing.
22:49:52 "player.c:1141" Connection 1: set conn->input_rate: 48000.
A session where a stale 44.1 kHz rate was present:
22:53:28 "player.c:1141" Connection 1: set conn->input_rate: 44100.
22:53:28 "rtsp.c:1411" Connection 1: SETRATEANCHORI ...
22:53:28 "rtsp.c:1473" Connection 1: SETRATEANCHORI Start playing.
22:53:29 "player.c:1141" Connection 1: set conn->input_rate: 48000.
Patched test with -250 ms:
rtsp.c:2939" Connection 1: set initial buffered input rate to 48000 from audioFormatIndex 23 (AAC/48000/F24/2).
rtsp.c:1457" Connection 1: buffered latency offset -0.250000 seconds at 48000 FPS is -12000 frames; raw anchor 232634705, adjusted anchor 232646705.
Patched test with +250 ms:
rtsp.c:2939" Connection 1: set initial buffered input rate to 48000 from audioFormatIndex 23 (AAC/48000/F24/2).
rtsp.c:1457" Connection 1: buffered latency offset 0.250000 seconds at 48000 FPS is 12000 frames; raw anchor 233388942, adjusted anchor 233376942.
System Information.
Raspberry Pi 4 Model B Rev 1.5
Debian GNU/Linux 13 (trixie)
Linux 6.18.39+rpt-rpi-v8, aarch64
Output:
USB-C to 3.5mm Headphone Jack Adapter
ALSA USB Audio
No PulseAudio or PipeWire
Configuration Information.
Original tested version:
5.2.1-AirPlay2-smi10-OpenSSL-Avahi-ALSA-soxr-metadata-mqtt-sysconfdir:/etc
NQPTP:
Version 1.2.8, shared-memory interface smi10
Relevant configuration:
general = {
output_backend = "alsa";
audio_backend_latency_offset_in_seconds = -0.250;
};
alsa = {
output_device = "softvol_boost";
};
Build options:
./configure --sysconfdir=/etc \
--with-alsa \
--with-soxr \
--with-avahi \
--with-ssl=openssl \
--with-systemd-startup \
--with-airplay-2 \
--with-metadata \
--with-mqtt-client
PulseAudio or PipeWire installed?
How did you install Shairport Sync?
Built from source
Check previous issues
What happened?
On Shairport Sync 5.2.1 in AirPlay 2 mode, changing audio_backend_latency_offset_in_seconds did not reliably produce the requested timing change for buffered 48 kHz AAC streams.
I tested offsets of -0.250 and +0.250 seconds. I expected these to shift the RTP anchor by -12,000 and +12,000 frames respectively at 48,000 frames/sec.
The apparent cause is in
handle_setrateanchori():For buffered stream type 103, SETRATEANCHORI can arrive before the first encoded audio block. At that point conn->input_rate has not necessarily been established by prepare_decoding_chain().
Observed results before the fix:
In one session conn->input_rate was still zero, so the configured offset produced no RTP-anchor adjustment.
In another 48 kHz session it contained a stale 44,100 value, producing 11,025 frames for 250 ms instead of 12,000.
The first audio block later changed conn->input_rate to 48,000, after the
anchor had already been processed.
Steps to reproduce:
I tested a fix that reads audioFormatIndex during buffered stream SETUP, maps it to the initial SSRC format, and sets conn->input_rate before SETRATEANCHORI is received. The actual packet format remains authoritative and can update the rate later.
With that change, the same tests consistently produced the expected ±12,000 frame adjustments.
Tested patch and commit:
prhodey@30812cd
Comparison against upstream 5.2.1:
prhodey/shairport-sync@5.2.1...multiroom-5.2.2
Relevant log output
System Information.
Raspberry Pi 4 Model B Rev 1.5
Debian GNU/Linux 13 (trixie)
Linux 6.18.39+rpt-rpi-v8, aarch64
Output:
USB-C to 3.5mm Headphone Jack Adapter
ALSA USB Audio
No PulseAudio or PipeWire
Configuration Information.
Original tested version: 5.2.1-AirPlay2-smi10-OpenSSL-Avahi-ALSA-soxr-metadata-mqtt-sysconfdir:/etc NQPTP: Version 1.2.8, shared-memory interface smi10 Relevant configuration: general = { output_backend = "alsa"; audio_backend_latency_offset_in_seconds = -0.250; }; alsa = { output_device = "softvol_boost"; }; Build options: ./configure --sysconfdir=/etc \ --with-alsa \ --with-soxr \ --with-avahi \ --with-ssl=openssl \ --with-systemd-startup \ --with-airplay-2 \ --with-metadata \ --with-mqtt-clientPulseAudio or PipeWire installed?
How did you install Shairport Sync?
Built from source
Check previous issues