Streams AirPlay audio to OpenHome/Songcast receivers as OHU unicast PCM
(16/24-bit). Sends are paced on the PTP master clock so receivers slave
to the AirPlay group clock through their buffer-fill servo; MediaLatency
carries the phase, matching the wire behaviour of Linn's own sender
(zero flags and timestamps). delay() reports the newest frame's playtime
lead so shairport feeds a receiver latency ahead. Handles Join, Listen,
Leave and Resend with a frame history, and forwards track metadata and
metatext from the metadata hub.
With -r <name>, ohm_upnp controls the receiver over UPnP: discovered by
friendly name via SSDP at time of use, woken, switched to its Songcast
source and pointed at this sender when a session starts; volume follows
the AirPlay slider capped at the device's VolumeLimit; standby follows
some minutes after the session ends.
Summary of changes:
* If the output rate is different to the input rate (e.g. 48,000 vs 44,100), look for the deepest output bit depth so that the transcoder has the maximum dynamic range available to minimise transcoding inaccuracies.
* Fix a bug whereby the audio backend latency offset was mishandled in AirPlay 2 operation.
* Fix an output format selection bug.
* Update the README reference to the MPRIS specification to the latest version.
* Remove the explicit `-` for `xxd` to read from `STDIN`. It's not necessary, and removing it makes it easier to package Shairport Sync on other build systems, such as OpenWrt.
Enable the AirPlay 2 build to operate an optional classic-AirPlay-only service or to gracefully degrade to classic AirPlay, as follows:
1. Add a new command-line option '-—service-type=<type>' and an equivalent configuration entry 'service_type = "<type>"' in the 'general' section of the configuration file,
where <type> can be "auto", "classic" or "airplay2":
1. "auto" (default) means that the service will be AirPlay 2 if NQPTP is running. If NQPTP is not running, classic AirPlay service will be provided instead, and in that case,
"(Classic)" will be appended to the default AirPlay service name visible to AirPlay clients like Apple Music, for example "RaspberryPi3B (Classic)".
2. "classic" means the service will be classic AirPlay (aka AirPlay 1).
3. "airplay2" means the service will be the modern AirPlay 2. In this case, as distinct from "auto", if NQPTP is not running, Shairport Sync will log an error and terminate.
2. In the systemd service file, NQPTP is now a "Want" rather than a "Require". If it's present, then it will be launched before Shairport Sync. If it's absent, Shairport Sync will launch anyway.
3. Improve the delivery of input format changes and emit 'sdsc' metadata when changes occur.
4. Emit new format information in the log if statistics is enabled.
Docker Changes
1. Support for linux/arm/v6 has been dropped, as Docker is no longer supported.
2. NQPTP is not started in the AirPlay 2 Docker image if '--service-type=classic' or '--service-type=airplay1' is in the command line options at the end of the docker run command.
The purpose is to ensure that ports 319 and 320 are left alone when the AirPlay 2 image is set to provide Classic service only.
Note that setting the configuration file 'service_type' to 'classic' will not prevent NQPTP from starting up -- you must use the command line option.
3. A new "dev" target has been added. It is a large image containing the custom-built FFmpeg library, NQPTP, Avahi and D-Bus along with the Shairport Sync source and
all necessary development tools. When started, Avahi, D-Bus and NQPTP are all installed and running. The bash shell has also been added and is entered.
Stability Improvements
Reorganise session preemption to fully terminate the existing session before starting a new one.
Don't delay closing the event port to wait for it to be closed at the client end.
Add a safe_socket_close() function to ensure sockets are fully closed. Use -1 to designate closed rather than 0, to prevent attempts to reclose sockets, causing mayhem.
Re-order FFmpeg decommissioning during teardown.
1. check_classic_mac_basic.yml — update to latest macOS-latest
2. docker-on-push-tag-or-pr — dependant updates
3. FFTConvolver — fix a compilation warning when the DEBUG flag is turned off
4. Reorganise some source files — e.g. move most of the metadata stuff into a subdirectory
5. Remove unused special-purpose AirPlay 2 RC event handler.
6. Reorganise source files and source code relating to the standard event handler.
7. Check configuration settings a little more carefully to offer more meaningful diagnostics.
8. Add password to AirPlay 2 and reorganise initialisation to set AirPlay 2 flags accordingly. Also, remove redundant airplay_pin.
9. Remove redundant debug facility definitions from common.h
10. Make it possible to omit all the dacp stuff from a build.
11. Make it possible to omit metadata multicast from a build.
12. Add AP2-native metadata by setting bit 50 of features to true.
13. Improve stability when pre-empting an existing play session.
14. Fix a few compiler warnings in the pair_ap library.
15. Ensure that the audio format is known before starting synchronisation.
16. Improve handle_configure to set/clear a new config setting. Doesn’t seem to do anything…
17. Experimentally turn off bit 46 of AirPlay 2 features — seems to stop failing pair-verify attempts.
New Features:
Multi-Channel and High-Resolution Audio Support
48,000 frames per second ("48k") operation.
48k lossless stereo support.
5.1 and 7.1 surround sound support.
Multi-channel and multi-rate operation on ALSA, PipeWire, PulseAudio, FreeBSD, stdout and Unix pipe output backends.
Automatic Audio Format Selection
Flexible and controllable output format selection.
Automatic rate, sample format, and channel count selection.
Full FFmpeg Integration
Support for transcoding.
Advanced resampling capabilities.
New audio format support.
Enhanced Resampling
New vernier resampling and interpolation method optimized for low-power CPUs.
Better performance on resource-constrained devices.
Convolution and Loudness Enhancements:
Convolution system is now multithreaded and works on stereo and multichannel audio at 48k and 44.1k.
Multiple impulse response (IR) files can now be provided via convolution_ir_files setting.
New convolution_thread_pool_size setting for multithreaded processing (defaults to 1).
Loudness processing now works with stereo and multichannel audio at 48k and 44.1k.
Updated to the most recent HiFi-LoFi FFT convolver.
MQTT Enhancements:
Added new publish_retain boolean option. When enabled, published MQTT messages have the retain flag set, so the MQTT broker stores the last message per topic and new subscribers receive the most recent value immediately. Thanks to lululombard for PR #2142.
D-Bus Enhancements:
Added new dbus_default_message_bus command-line argument (can be system or session) to set the default message bus for both D-Bus native service and MPRIS service.
Performance Improvements:
Enhanced compatibility with AirPlay 2 AutoMix and Smart Tracklists resulting in less unexplained track skipping.
Better operation on low-power devices down to Raspberry Pi B.
Improved efficiency on embedded systems.
Enhanced timestamp handling for better synchronization.
Improved sync error calculation.
Rebuilt buffered audio processor for cleaner handling of immediate and deferred flush requests.
Docker Enhancements:
Reduced Docker image sizes with slimmed-down FFmpeg library.
Removed dhclient from Docker images for smaller footprint.
Bug Fixes:
Fixed MQTT warning on service startup: "Could not establish a mqtt connection". The startup script now correctly states that the mosquitto service is required. Thanks to Hugo Villeneuve for PR #2137.
Fixed compatibility with mbedtls library version 3.4+ (present on recent Linux versions). Thanks to Christian Beier for finding and fixing the bug.
Fixed PulseAudio backend so that PA_ERR_NODATA returns "No latency data yet". Thanks to Vladimir Shakov for the report and fix.
Ensured old flush requests are deleted when a new play session starts. Thanks to saujanyashah for the report.
Fixed format warnings on 64-bit and 32-bit systems
Removed compilation warnings on 32-bit builds
Improved argument checking for debug(), inform(), warn() and die() functions
Fixed "daemon" typos throughout codebase. Thanks to Chris Boot for PR #1981.
Added warning if a convolution impulse response file cannot be read due to bad path or permissions
Build System Improvements:
Unified service file with variable substitution for Avahi support, making it easier to add future service dependencies. Thanks to Hugo Villeneuve.
Network interface selection now only considers interfaces that are up, running and not loopback interfaces. Thanks to Carl Johnson for the suggestion.
Configuration File Changes and Deprecations
New settings: convolution_ir_files (replaces convolution_ir_file), convolution_enabled (replaces convolution), convolution_max_length_in_seconds (replaces convolution_max_length), loudness_enabled (replaces loudness).
New convolution_thread_pool_size setting (defaults to 1).
Deprecated settings: convolution_ir_file, convolution, convolution_max_length, loudness.
Corresponding D-Bus methods and properties have been updated.
Deprecation Notice:
The Jack Audio and soundio backends are deprecated and will be removed in a future release. Consider using the updated PipeWire backend instead.
Documentation Updates
Updated BUILD.md with latest build instructions.
Updated AIRPLAY2.md with feature information.
Enhanced convolution and loudness documentation.
Maintenance:
Fixed FFmpeg deprecation warnings.
Bumped actions/checkout from 6.0.1 to 6.0.2.
Bumped docker/login-action from 3.6.0 to 3.7.0.
Bumped docker/build-push-action from 6.13.0 to 6.15.0.
Bumped docker/setup-qemu-action from 3.4.0 to 3.6.0.
Bumped docker/setup-buildx-action from 3.9.0 to 3.10.0.
This fixes the following warning:
shairport-sync[293]: [MQTT]: Could not establish a mqtt connection
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Use variable substitution to simplify service file for optional avahi.
This will also help to simplify adding future service dependencies.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
(1) to be multithreaded,
(2) to work on multichannel audio and
(3) to work on 48k and 44.1k audio.
Allow multiple impulse response (IR) files with a new setting: "convolution_ir_files"
When convolution starts, Shairport Sync will look for an IR file with a sample rate
matching the input (44.1k or 48k) and channel count.
If one can't be found, it will look for a single-channel IR file with the same rate.
It will always choose the first match in the file list supplied "convolution_ir_files".
Allow multithreading -- use the "convolution_thread_pool_size" to set the number of threads to use.
Deprecate "convolution" -- use "convolution_enabled" instead.
Deprecate "convolution_max_length" -- use "convolution_max_length_in_seconds" instead.
Deprecate "convolution_ir_file" -- use "convolution_ir_files" instead.
Update corresponding D-Bus methods and properties.
Update the loudness code to work on 48k and well as 44.1k audio and with multichannel audio.
Deprecate "loudness" -- use "loudness_enabled" instead.
Update corresponding D-Bus methods and properties.
Fix a deprecated FFmpeg warning.
Update HiFi-LoFi FFT convolver to latest available.
- 48,000 frames per second operation,
- 48k lossless stereo, 5.1 and 7.1 surround sound
- Multichannel and multi rate operation on ALSA, PipeWire, PulseAudio, FreeBSD, stdout and unix pipe output backends.
Automatic, flexible and controllable output format (rate, sample format and channel count) selection.
Full FFmpeg integration to support transcoding, resampling, and new audio formats.
Better operation on lower powered devices down to e.g. Raspberry Pi B.
Reduced Docker image sizes with a slimmed-down FFmpeg library.
Enhanced timestamp handling for better synchronization.
Improved the sync error calculation.
A new "vernier" resampling and interpolation method for low-power CPUs.
Bug fixes and minor enhancements.
Note -- there are many breaking changes from previous versions of Shairport Sync!
Limit the maximum number of open file handles in Docker images.
Increase the level of optimisation (to -O3) while building the Shairport Sync application itself.
Enabled termination of a disconnected session in AirPlay 2 operation after a timeout, which was disabled by default.
Fixed a bug that prevented Shairport Sync from terminating cleanly when a fatal error that occurred while directly accessing the alsa output device.
Fixed a bug that prevented Shairport Sync from recovering cleanly if a player disconnected without warning. The problem was that the player thread would not respond to cancel request. Fixed by moving a pthreadtestcancel() call to the innermost loop.
Fixed compilation errors on old versions of Mac OS X by, reordering some of the files to be included in shairport.c.
Avoided using TCP_KEEPINTVL and TCP_KEEPCNT if they are not defined (they are not defined in older versions of Mac OS X).
Fixed a race condition with the metadata queues. The problem was that the queues were being initialised by threads launched by the main thread which, having started the threads, proceeded to use the queues. But if the threads were late in starting, the queues might not be initialised by the time the main thread tried to use them. Fixed by initialising the queues in the main thread.
Enable the ALSA backend to access mixers on a devices with a hdmi: prefix.
Update the help text for the ALSA backend to denote HDMI devices using the hdmi: prefix rather than hw:.
Manage thread cancellation state explicitly in audio_ao.c
CAR INSTALL guide: Simplify some of the wording. Change order and allow a few seconds before starting systemd-timesync service.
Update to 4.3.2
**Enhancements**
* A totally new PipeWire backend featuring full synchronisation.
**Bug Fixes**
* Stability improvements for the PulseAudio backend.
* Fix a crash when the Avahi subsystem became disconnected. This is normally a rare occurrence, but Shairport Sync was not dereferencing obsolete data correctly when it happened.
* Set and reset Bonjour flags correctly when it's a Classic Airplay session in AirPlay 2 operation.
* Fix a number of FreeBSD compilation errors and warnings.
* Fix various errors when breaking into an existing session to terminate it. Thanks again to [aaronk6](https://github.com/aaronk6).
* Fix some debug message errors, sigh. Thanks to [Nathan Gray](https://github.com/n8gray).