AirPlay and AirPlay 2 audio player
Go to file
Mike Brady 45767ef94a
Update check_classic_mac_basic.yml
Simplify basic macOS check build.

Extra CFLAG settings to configure.ac for libconfig libpopt and openssl/libcrypto enable compilation on macOS without extra flag settings.
2024-04-25 15:17:40 +01:00
.github Update check_classic_mac_basic.yml 2024-04-25 15:17:40 +01:00
ADVANCED TOPICS Update PulseAudioAndPipeWire.md 2023-03-24 10:58:15 +00:00
FFTConvolver Add D-Bus convolution filter controls; enable convolution filters to be turned on and off or changed; enable convolution gain to be checked and changed. 2019-11-11 21:45:29 +00:00
docker in the docker build process, skip the make install for nqptp and take the binary of nqptp from where it is built 2023-09-11 17:46:00 +01:00
documents Update sample dbus commands 2022-08-10 10:04:58 +01:00
man Include the HTML version of ther page. 2022-10-29 09:41:14 +01:00
pair_ap Update the pair_ap library. Thanks again to ejurgensen for this code. 2022-09-26 17:24:04 +01:00
plists Remember to add some exta fields later... 2021-12-06 18:08:35 +00:00
scripts Move the PipeWire stanza up in the configuration file. 2023-10-06 11:13:30 +01:00
tests This is 3.3.8rc3 2021-01-24 18:01:39 +00:00
tinyhttp Add tinyhttp as a subdirectory and not a submodule for ease of switching from master to development 2021-07-06 19:41:24 +01:00
.dockerignore s6 improvements and docker build changes 2022-08-20 00:02:54 +01:00
.gitignore Ignore some intermediate productes. 2022-10-24 11:56:09 +01:00
.gitmodules continue to remover pair_ap as a git submodule. 2021-07-07 13:54:18 +00:00
.travis.yml Update .travis.yml 2017-01-30 23:02:07 +00:00
ADDINGTOHOME.md Uncheck "require password" 2023-05-28 08:10:13 +01:00
AIRPLAY2.md Include the HTML version of ther page. 2022-10-29 09:41:14 +01:00
AUTHORS moving to using autotools 2014-04-30 20:47:48 +01:00
BUILD.md Update BUILD.md 2023-05-23 17:11:26 +01:00
CAR INSTALL.md Update CAR INSTALL.md 2023-10-15 22:24:03 +01:00
CONFIGURATION FLAGS.md Big documentation reorganisation. Comments wlecome! 2022-07-25 14:44:57 +01:00
COPYING Update COPYING 2014-10-25 14:25:21 +01:00
CYGWIN.md Update CYGWIN.md 2021-07-07 09:02:15 +01:00
ChangeLog moving to using autotools 2014-04-30 20:47:48 +01:00
LIBSOXR.md Update LIBSOXR.md 2017-04-16 20:04:37 +01:00
LICENSES Add tinyhttp code for sending and reading responses. Clean up some dacp routines. Most new and modified rooutines untested. 2017-12-18 18:50:01 +00:00
MQTT.md Merge branch 'development' into patch-2 2023-03-19 08:52:38 +00:00
Makefile.am Small bug fixes 2023-09-11 15:58:49 +01:00
NEWS Update NEWS 2016-03-02 17:41:33 +00:00
OPENBSD.md Bring over some updates that were applied to the master branch. 2021-07-22 17:33:31 +01:00
README moving to using autotools 2014-04-30 20:47:48 +01:00
README.md Merge updates from the development branch into the master branch as 4.2.1 2023-09-16 18:20:12 +01:00
RELEASENOTES.md Actually make 4.2.1 4.3, since there have been enhancements. 2023-09-16 18:50:41 +01:00
REPORTING ISSUES.md Update REPORTING ISSUES.md 2020-06-12 09:49:27 +01:00
TROUBLESHOOTING.md Update TROUBLESHOOTING.md 2022-12-08 09:37:59 +00:00
activity_monitor.c Try again to ensure an active_end metadata item is emitted if the player exits while playing. 2023-08-27 15:54:16 +01:00
activity_monitor.h find . \( -name \*.cpp -or -name \*.h -or -name \*.c \) -exec clang-format -i -style='{BasedOnStyle: llvm, IndentWidth: 2, ColumnLimit: 100}' '{}' \; 2019-06-19 19:06:54 +01:00
alac.c 3.1.2 pretty-print using clang-format 2017-09-07 12:02:00 +01:00
alac.h 3.3.7rc0 2020-07-06 17:09:15 +01:00
apple_alac.cpp Squashed commit of the following: 2020-02-20 21:32:35 +00:00
apple_alac.h Squashed commit of the following: 2020-02-20 21:32:35 +00:00
audio.c pipewire: add initial support 2021-04-01 10:12:42 -07:00
audio.h Squashed commit of the following: 2022-09-12 15:19:52 +01:00
audio_alsa.c format adjustments 2023-09-11 16:01:38 +01:00
audio_ao.c Specify libao input channel ordering 2023-05-24 15:15:09 +10:00
audio_dummy.c Quieten a debug message. 2022-10-07 15:43:28 +01:00
audio_jack.c format adjustments 2023-09-11 16:01:38 +01:00
audio_pa.c Remove code that was double-deallocating settings strings. 2023-10-06 10:50:30 +01:00
audio_pipe.c Clang cleanup 2022-11-18 18:14:50 +00:00
audio_pw.c Typo 2023-10-08 17:40:43 +01:00
audio_sndio.c Squashed commit of the following: 2022-09-12 15:19:52 +01:00
audio_soundio.c Add a new command line option "--displayConfig" to give version string, command line and active configuration file name and settings. 2022-10-11 13:05:13 +01:00
audio_stdout.c Call the unfixable error handler if the output device can't be opened or disappears. Clang-format. 2022-12-30 18:46:53 +00:00
common.c Add a pthread_cleanup compatible function to release a pthread_rwlock. 2023-09-21 15:50:43 +01:00
common.h Add PipeWire sink target setting. Fix PipeWire node name code, duh, remove code that was double-deallocating settings strings. 2023-10-06 10:51:49 +01:00
configure.ac Merge branch 'development' 2023-10-15 18:42:38 +01:00
dacp.c format adjustments 2023-09-11 16:01:38 +01:00
dacp.h Squashed commit of the following: 2020-02-20 21:32:35 +00:00
dbus-service.c clang format 2023-09-21 16:45:22 +01:00
dbus-service.h Squashed commit of the following: 2020-02-20 21:32:35 +00:00
definitions.h Changes to allow it to compile in FreeBSD and fix a few issues that were picked up by clang 10. 2021-06-22 13:49:11 +01:00
loudness.c Fix D-Bus loudness switch silencing output. Rename LoudnessFiulterActive to Loudness. Add Convolution, ConvolutionGain and ConvolutionImpulseResponseFile properties to the D-Bus interface. 2019-11-10 18:05:59 +00:00
loudness.h Tidy up source using clang-format 2017-07-31 11:57:57 +02:00
mdns.c Second attempt. Modify the generation of the 12-digit classic AirPlay service name prefix so that it depends on the service name as well as the hardware address. 2022-11-17 10:31:51 +00:00
mdns.h Working to check for divide / mod by 0's 2021-11-17 10:35:21 +00:00
mdns_avahi.c Very very rarely, the avahi client becomes disconnected. 2023-09-27 10:36:28 +01:00
mdns_dns_sd.c Accommodate but do not use extra texts and name for a secondary boujour message. 2022-08-08 12:18:36 +01:00
mdns_external.c Squashed commit of the following: 2022-09-12 15:19:52 +01:00
mdns_tinysvcmdns.c Squashed commit of the following: 2022-09-12 15:19:52 +01:00
metadata_hub.c format adjustments 2023-09-11 16:01:38 +01:00
metadata_hub.h Call the unfixable error if the output device can't be opened or disappears. Clang-format. 2022-12-30 18:36:33 +00:00
mpris-service.c Add new metadata item: sps:songdatakind, derived from the asdk metadata token. It seems to indicate a timed item (0) or an untimed stream (1). Add output format, output frame rate, stream type (Realtime/Buffered/Classic) properties. Update MQTT appropriately. 2022-11-12 16:42:25 +00:00
mpris-service.h Squashed commit of the following: 2020-02-20 21:32:35 +00:00
mqtt.c Parse phbt/phb0 metddata tokens. 2022-12-05 11:37:22 +00:00
mqtt.h Move ab_mutex, flow control CV and flush mutex initialisation and teardown out of the player thread. Thus remove need for player theread lock. Format some of the surce files. 2018-07-14 13:38:29 +01:00
nqptp-shm-structures.h clang format 2023-09-21 16:45:22 +01:00
org.gnome.ShairportSync.xml Add "FirstFramePostion" property set when first frame of a play session is sent. 2022-11-28 15:09:43 +00:00
org.mpris.MediaPlayer2.xml Squashed commit of the following: 2020-02-20 21:32:35 +00:00
player.c Don't mute if the volume control is at minimum (-144.0) and ignore_volume_control is seelcted. 2023-09-29 09:41:07 +01:00
player.h move the declaration of principal_conn_lock from player.h to rtsp.h where it should be. 2023-09-21 15:49:25 +01:00
ptp-utilities.c Fix potential bug if the timing data is inconsistent for 10 tries. 2023-09-30 15:40:40 +01:00
ptp-utilities.h Move to smi version 10, read-only interface, no mutex, write and read each record twice to ensure it is not inconsistent when read. 2023-09-11 16:02:49 +01:00
rtp.c Fix a benign warning from Clang 16 on FreeBSD 2023-09-20 11:46:38 +01:00
rtp.h Tidy up write encrypted. Explore some of the remote_control connections. Not working. 2022-06-23 09:40:30 +01:00
rtsp.c Change response to a /feedback message in a Classic AirPlay session to 501 Not Implmemented instead of 200 OK. 2023-10-13 07:52:51 +01:00
rtsp.h move the declaration of principal_conn_lock from player.h to rtsp.h where it should be. 2023-09-21 15:49:25 +01:00
shairport-sync-dbus-test-client.c 3.3.7rc0 2020-07-06 17:09:15 +01:00
shairport-sync-mpris-test-client.c Squashed commit of the following: 2020-02-20 21:32:35 +00:00
shairport-sync.spec Update shairport-sync.spec 2021-04-26 11:35:11 +01:00
shairport.c Fix warning picked up on FreeBSD15 2023-09-20 11:32:26 +01:00
tinysvcmdns.c Fix tinysvcmdns: rr_data_len goes beyond packet buffer 2021-06-21 06:37:50 +02:00
tinysvcmdns.h 3.1.2 pretty-print using clang-format 2017-09-07 12:02:00 +01:00

README.md

Shairport Sync

Shairport Sync is an AirPlay audio player for Linux and FreeBSD. It plays audio streamed from Apple devices and from AirPlay sources such as OwnTone (formerly forked-daapd).

Shairport Sync can be built as an AirPlay 2 player (with some limitations) or as "classic" Shairport Sync a player for the older, but still supported, AirPlay (aka "AirPlay 1") protocol.

Metadata such as artist information and cover art can be requested and provided to other applications. Shairport Sync can interface with other applications through MQTT, an MPRIS-like interface and D-Bus.

Shairport Sync does not support AirPlay video or photo streaming.

Quick Start

Features

  • Outputs AirPlay audio to ALSA, sndio, PulseAudio, Jack Audio, to a unix pipe or to STDOUT. It also has experimental support for PipeWire and limited support for libao and for libsoundio.
  • Metadata — Shairport Sync can deliver metadata supplied by the source, such as Album Name, Artist Name, Cover Art, etc. through a pipe or UDP socket to a recipient application program — see https://github.com/mikebrady/shairport-sync-metadata-reader for a sample recipient. Sources that supply metadata include iTunes and the Music app in macOS and iOS.
  • An interface to MQTT, a popular protocol for Inter Process Communication, Machine-to-Machine, Internet of Things and Home Automation projects. The interface provides access to metadata and artwork, and has limited remote control.
  • Digital Signal Processing facilities please see the DSP Wiki Page Guide. (Thanks to Yann Pomarède for the code and to Paul Wieland for the guide.)
  • An MPRIS-like interface, partially complete and very functional, including access to metadata and artwork, and limited remote control.
  • A native D-Bus interface, including access to metadata and artwork, limited remote control and system settings.
  • Better Volume Control — Shairport Sync offers finer control at very top and very bottom of the volume range. See http://tangentsoft.net/audio/atten.html for a good discussion of audio "attenuators", upon which volume control in Shairport Sync is modelled. See also the diagram of the volume transfer function in the documents folder. In addition, Shairport Sync can offer an extended volume control range on devices with a restricted range.
  • Support for the Apple ALAC decoder (library available here).
  • Output bit depths of 8, 16, 24 and 32 bits, rather than the standard 16 bits.
  • Output frame rates of 44,100, 88,200, 176,000 or 352,000 frames per second.

Some features require configuration at build time see CONFIGURATION FLAGS.md.

Status

Shairport Sync was designed to run best on stable, dedicated, stand-alone low-power "headless" systems with ALSA as the audio system and with a decent CD-quality Digital to Analog Converter (DAC).

Shairport Sync runs on recent (2018 onwards) Linux systems and FreeBSD from 12.1 onwards. It requires a system with the power of a Raspberry Pi 2 or a Pi Zero 2 or better.

Classic Shairport Sync runs on a wider variety of Linux sytems, including OpenWrt and Cygwin and it also runs on OpenBSD. Many embedded devices are powerful enough to power classic Shairport Sync.

Heritage and Acknowledgements

The functionality offered by Shairport Sync is the result of study and analysis of the AirPlay and AirPlay 2 protocols by many people over the years. These protocols have not been officially published, and there is no assurance that Shairport Sync will continue to work in future.

Shairport Sync is a substantial rewrite of the fantastic work done in Shairport 1.0 by James Wah (aka abrasive), James Laird and others — please see this list of the contributors to Shairport 1.x and Shairport 0.x. From a "heritage" point of view, Shairport Sync is a fork of Shairport 1.0.

For the development of AirPlay 2 support, special thanks are due to:

Much of Shairport Sync's AirPlay 2 functionality is based on ideas developed at the openairplay airplay2-receiver repository. It is a pleasure to acknowledge the work of the contributors there.

Thanks to everyone who has supported and improved Shairport Sync over the years.

More about Shairport Sync

The audio that Shairport Sync receives is sent to the computer's sound system, to a named unix pipe or to STDOUT. By far the best sound system to use is ALSA. This is because ALSA can give direct access to the Digital to Analog Converter (DAC) hardware of the machine. Audio samples can be sent through ALSA directly to the DAC, maximising fidelity, and accurate timing information can be obtained from the DAC, maximising synchronisation. Direct access to hardware is given through ALSA devices with names beginning with hw:.

Synchronised Audio

Shairport Sync offers full audio synchronisation. Full audio synchronisation means that audio is played on the output device at exactly the time specified by the audio source. To accomplish this, Shairport Sync needs access to audio systems such as ALSA on Linux and sndio on FreeBSD that provide very accurate timing information about audio being streamed to output devices. Ideally, Shairport Sync should have direct access to the output device used, which should be a real sound card capable of working with 44,100, 88,200 or 176,400 samples per second, interleaved PCM stereo of 8, 16, 24 or 32 bits. Using the ALSA sound system, Shairport Sync will choose the greatest bit depth available at 44,100 samples per second, resorting to multiples of 44,100 if it is not available. You'll get a message in the log if there's a problem. With all other sound systems, a sample rate of 44,100 is chosen with a bit depth of 16 bit.

Shairport Sync works well with PulseAudio, a widely used sound server found on many desktop Linuxes. While the timing information is not as accurate as that of ALSA or sndio, it is often impractical to remove or disable PulseAudio.

For other use cases, Shairport Sync can provide synchronised audio output to a unix pipe or to STDOUT, or to audio systems that do not provide timing information. This could perhaps be described as partial audio synchronisation, where synchronised audio is provided by Shairport Sync, but what happens to it in the subsequent processing chain, before it reaches the listener's ear, is outside the control of Shairport Sync.

Latency, "Stuffing", Timing

AirPlay protocols use an agreed latency a time lag or delay between the time represented by a sound sample's timestamp and the time it is actually played by the audio output device, typically a Digital to Audio Converter (DAC). Latency gives players time to compensate for network delays, processing time variations and so on. The latency is specified by the audio source when it negotiates with Shairport Sync. AirPlay sources set a latency of around 2.0 to 2.25 seconds. AirPlay 2 can use shorter latencies, around half a second.

As mentioned previously, Shairport Sync implements full audio synchronisation when used with ALSA, sndio or PulseAudio audio systems. This is done by monitoring the timestamps present in data coming from the audio source and the timing information coming back from the audio system itself. To maintain the latency required for exact synchronisation, if the output device is running slow relative to the source, Shairport Sync will delete frames of audio to allow the device to keep up. If the output device is running fast, Shairport Sync will insert ("stuff") extra frames to keep time. The number of frames inserted or deleted is so small as to be almost inaudible on normal audio material. Frames are inserted or deleted as necessary at pseudorandom intervals. Alternatively, with libsoxr support, Shairport Sync can resample the audio feed to ensure the output device can keep up. This is less obtrusive than insertion and deletion but requires a good deal of processing power — most embedded devices probably can't support it. If your computer is fast enough, Shairport Sync will, by default, automatically choose this method.

Stuffing is not done for partial audio synchronisation the audio samples are simply presented at exactly the right time to the next stage in the processing chain.

Timestamps are referenced relative to the source computer's clock the "source clock", but timing must be done relative to the clock of the computer running Shairport Sync the "local clock". So, Shairport Sync synchronises the source clock and the local clock, usually to within a fraction of a millisecond. In AirPlay 2, this is done with the assistance of a companion application called NQPTP using a PTP-based timing protocol. In classic AirPlay, a variant of NTP synchronisation protocols is used.