Skip to content

Commit

Permalink
This squashed commit comprises a long series of improvements, bug fix…
Browse files Browse the repository at this point in the history
…es, optimizations, and new feature additions:

 - 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!
  • Loading branch information
mikebrady committed Feb 23, 2025
1 parent 588e6a5 commit 6014351
Show file tree
Hide file tree
Showing 110 changed files with 12,320 additions and 7,663 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/check_ap2_systemd_basic.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Basic ALSA configuration for systemd, using a build folder.
name: systemd, alsa, pipewire, build folder.

on:
workflow_dispatch:
Expand All @@ -10,18 +10,18 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
- name: Install Dependencies
run: sudo apt-get -y --no-install-recommends install xmltoman libpopt-dev libconfig-dev libasound2-dev avahi-daemon libavahi-client-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev
run: sudo apt-get -y --no-install-recommends install libpipewire-0.3-dev libplist-utils xmltoman libpopt-dev libconfig-dev libasound2-dev avahi-daemon libavahi-client-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev libgcrypt-dev uuid-dev
- name: Configure
run: |
mkdir build
cd build
autoreconf -i ..
../configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-airplay-2
../configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl --with-systemd-startup --with-airplay-2 --with-pipewire
- name: Make
run: |
cd build
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/check_ap2_systemd_full.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Configuration (without pa, soundio or apple-alac) for systemd.
name: systemd, alsa, ao, dummy, jack, pipe, stdout

on:
workflow_dispatch:
Expand All @@ -10,16 +10,16 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
- name: Install Dependencies
run: sudo apt-get -y --no-install-recommends install xmltoman libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libmosquitto-dev avahi-daemon libavahi-client-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev
run: sudo apt-get -y --no-install-recommends install libglib2.0-dev libplist-utils xmltoman libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libmosquitto-dev avahi-daemon libavahi-client-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev libgcrypt-dev
- name: Configure
run: |
autoreconf -fi
./configure --sysconfdir=/etc --with-alsa --with-ao --with-dummy --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
./configure --sysconfdir=/etc --with-alsa --with-ao --with-dummy --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemd-startup --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
- name: Make
run: |
make -j
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/check_ap2_systemd_full_build_folder.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Configuration (without pa, soundio or apple-alac) for systemd, using a build folder.
name: systemd, alsa, pipewire, ao, dummy, jack, pipe, stdout,using a build folder.

on:
workflow_dispatch:
Expand All @@ -10,18 +10,18 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
- name: Install Dependencies
run: sudo apt-get -y --no-install-recommends install xmltoman libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev
run: sudo apt-get -y --no-install-recommends install libpipewire-0.3-dev libplist-utils xmltoman libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev libgcrypt-dev
- name: Configure
run: |
mkdir build
cd build
autoreconf -i ..
../configure --sysconfdir=/etc --with-alsa --with-ao --with-dummy --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
../configure --sysconfdir=/etc --with-alsa --with-pipewire --with-ao --with-dummy --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemd-startup --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
- name: Make
run: |
cd build
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/check_ap2_systemv_full.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Configuration (but without pa, soundio, apple-alac) for a System V system.
name: systemv, alsa, pipewire, ao, dummy, jack, pipe, stdout

on:
workflow_dispatch:
Expand All @@ -10,16 +10,16 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
- name: Install Dependencies
run: sudo apt-get -y --no-install-recommends install xmltoman libpopt-dev libdaemon-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev uuid-dev libgcrypt-dev
run: sudo apt-get -y --no-install-recommends install libpipewire-0.3-dev libplist-utils xmltoman libpopt-dev libdaemon-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libplist-dev libsodium-dev libavutil-dev libavcodec-dev libavformat-dev uuid-dev libgcrypt-dev
- name: Configure
run: |
autoreconf -i
./configure --sysconfdir=/etc --with-alsa --with-ao --with-dummy --with-libdaemon --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemv --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
./configure --sysconfdir=/etc --with-alsa --with-pipewire --with-ao --with-dummy --with-libdaemon --with-jack --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemv-startup --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-airplay-2
- name: Make
run: |
make -j
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check_classic_mac_basic.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Basic libao configuration for macOS with BREW -- classic only, because macOS can't host NQPTP.
name: macos classic, libao, BREW -- classic only, because macOS can't host NQPTP.

on:
workflow_dispatch:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/check_classic_systemd_basic.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Basic ALSA classic configuration for systemd, using a build folder.
name: systemd classic, alsa, using a build folder.

on:
workflow_dispatch:
Expand All @@ -10,7 +10,7 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
Expand All @@ -21,7 +21,7 @@ jobs:
mkdir build
cd build
autoreconf -i ..
../configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl --with-systemd
../configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl --with-systemd-startup
- name: Make
run: |
cd build
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/check_classic_systemd_full.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Classic (without pa, soundio, apple-alac) for systemd, using a build folder.
name: systemd classic, ffmpeg, alsa, pipewire, build folder.

on:
workflow_dispatch:
Expand All @@ -10,18 +10,18 @@ on:
jobs:
build:

runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.2.2
- name: Install Dependencies
run: sudo apt-get -y --no-install-recommends install xmltoman libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev
run: sudo apt-get -y --no-install-recommends install xmltoman libpipewire-0.3-dev libpopt-dev libconfig-dev libasound2-dev libao-dev libjack-dev libglib2.0-dev libmosquitto-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libavutil-dev libavcodec-dev libavformat-dev
- name: Configure
run: |
mkdir build
cd build
autoreconf -i ..
../configure --sysconfdir=/etc --with-alsa --with-ao --with-dummy --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-systemd --with-dbus-interface --with-mpris-interface --with-mqtt-client
../configure --sysconfdir=/etc --with-ffmpeg --with-alsa --with-pipewire --with-ao --with-dummy --with-pipe --with-stdout --with-soxr --with-avahi --with-ssl=openssl --with-dbus-interface --with-mpris-interface --with-mqtt-client --with-systemd-startup
- name: Make
run: |
cd build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,48 +20,6 @@ env:
NQPTP_BRANCH: main

jobs:
test-build-on-pull-request:
if: github.event_name == 'pull_request'
runs-on: ubuntu-22.04
steps:
- name: Checkout Repo
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}

- name: Set SHAIRPORT_SYNC_BRANCH env
run: |
SHAIRPORT_SYNC_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "Current SHAIRPORT_SYNC_BRANCH set to ${SHAIRPORT_SYNC_BRANCH}"
echo "SHAIRPORT_SYNC_BRANCH=${SHAIRPORT_SYNC_BRANCH}" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.8.0

- name: Build (classic)
uses: docker/build-push-action@v6.14.0
with:
context: ./
file: ./docker/classic/Dockerfile
push: false
build-args: |
SHAIRPORT_SYNC_BRANCH=${{ env.SHAIRPORT_SYNC_BRANCH }}
- name: Build
uses: docker/build-push-action@v6.14.0
with:
context: ./
file: ./docker/Dockerfile
push: false
build-args: |
SHAIRPORT_SYNC_BRANCH=${{ env.SHAIRPORT_SYNC_BRANCH }}
NQPTP_BRANCH=${{ env.NQPTP_BRANCH }}
build-and-publish:
if: github.event_name != 'pull_request'
runs-on: ubuntu-22.04
Expand All @@ -86,10 +44,10 @@ jobs:
echo "IMAGE_TAG_BASE=development" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0
uses: docker/setup-qemu-action@v3.4.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.8.0
uses: docker/setup-buildx-action@v3.9.0

- name: Login to Docker Registry
uses: docker/login-action@v3.3.0
Expand All @@ -98,7 +56,7 @@ jobs:
username: ${{ secrets.DOCKER_REGISTRY_USER }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}

- name: Build and push (classic)
- name: Build and Push (Classic)
uses: docker/build-push-action@v6.14.0
with:
context: ./
Expand All @@ -109,7 +67,7 @@ jobs:
build-args: |
SHAIRPORT_SYNC_BRANCH=${{ env.SHAIRPORT_SYNC_BRANCH }}
- name: Build and push
- name: Build and Push (AirPlay 2)
uses: docker/build-push-action@v6.14.0
with:
context: ./
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Only pushes the tag when it matches one of the following patterns:
# X, X.Y or X.Y.Z

name: Build and push docker (tag)
name: Build and push Docker images...

on:
workflow_dispatch:
Expand All @@ -16,8 +16,9 @@ on:
- '[0-9]+\.[0-9]+\.[0-9]+' # X.Y.Z

env:
DOCKER_PLATFORMS: linux/386,linux/amd64,linux/arm/v6,linux/arm64,linux/arm/v7
DOCKER_PLATFORMS: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64
NQPTP_BRANCH: main
LATEST_TAG: false

jobs:
main:
Expand All @@ -37,25 +38,26 @@ jobs:
- name: Set tag env
run: echo "GIT_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV

- name: Is branch "master"?
if: ${{ env.SHAIRPORT_SYNC_BRANCH == 'master' }}
run: echo "LATEST_TAG=true" >> $GITHUB_ENV

- name: Is branch "development"?
if: ${{ env.SHAIRPORT_SYNC_BRANCH == 'development' }}
run: |
echo "NQPTP_BRANCH=development" >> $GITHUB_ENV
- name: Is branch "danger-2301"?
if: ${{ env.SHAIRPORT_SYNC_BRANCH == 'danger-2301' }}
run: |
echo "NQPTP_BRANCH=development" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.3.0
uses: docker/setup-qemu-action@v3.4.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.8.0
uses: docker/setup-buildx-action@v3.9.0

- name: Login to Docker Registry
uses: docker/login-action@v3.3.0
with:
registry: ${{ secrets.DOCKER_REGISTRY }}
# registry: docker.io # default
username: ${{ secrets.DOCKER_REGISTRY_USER }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}

Expand All @@ -72,16 +74,16 @@ jobs:
build-args: |
SHAIRPORT_SYNC_BRANCH=${{ env.SHAIRPORT_SYNC_BRANCH }}
- name: Build and push
- name: Build and Push AirPlay 2 Version
uses: docker/build-push-action@v6.14.0
with:
context: ./
file: ./docker/Dockerfile
platforms: ${{ env.DOCKER_PLATFORMS }}
push: true
tags: |
${{ secrets.DOCKER_IMAGE_NAME }}:${{ env.GIT_TAG }}
${{ env.LATEST_TAG == 'true' && format('{0}:latest', secrets.DOCKER_IMAGE_NAME) || '' }}
mikebrady/sps-private:${{ env.GIT_TAG }}
mikebrady/sps-private:latest
build-args: |
SHAIRPORT_SYNC_BRANCH=${{ env.SHAIRPORT_SYNC_BRANCH }}
NQPTP_BRANCH=${{ env.NQPTP_BRANCH }}
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ scripts/shairport-sync.service
scripts/shairport-sync.service-avahi
scripts/shairport-sync
shairport-sync.core
gitversion.*
plist_xml_strings.*
gitversion-stamp
gitversion.h
plists/*.c
plists/*.h
plists/*.x

#Some dbus files that are automatically generated
/org.gnome.ShairportSync.service
Expand All @@ -45,8 +48,9 @@ plist_xml_strings.*
.DS_Store
shairport-sync.xcodeproj

# separate build directory
# separate build directories
build
classic

# vscode
.vscode
12 changes: 6 additions & 6 deletions ADVANCED TOPICS/AdjustingSync.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Adjusting Synchronisation on Shairport Sync ("SPS")
# Adjusting Synchronisation with Shairport Sync

Sometimes, a timing difference can be heard, where the audio coming from the SPS-powered device is slightly ahead or slightly behind another device playing in synchrony. This can sometimes be heard as an irritating "echo".
Sometimes, a timing difference can be heard, where the audio coming from the Shairport-Sync-powered device is slightly ahead or slightly behind another device playing in synchrony. This can sometimes be heard as an irritating "echo".

This is usually due to audio amplifier delays:

* If your audio output device (including the amplifier in a TV) includes any digital processing component, it probably delays audio while amplifying it.

* If your output device is a HDMI-connected device such as a TV or an AV Receiver (AVR), it will almost certainly delay audio by anything up to several hundred milliseconds.

In these circumstances, if the output from the SPS device is amplified by a conventional analog-only HiFi amplifier – which has almost no delay – it will be early by comparison with audio coming from the other device.
In these circumstances, if the output from the Shairport Sync device is amplified by a conventional analog-only HiFi amplifier – which has almost no delay – it will be early by comparison with audio coming from the other device.

Conversely, if the output from the SPS device is passed through an AVR, then it could be late by comparison with audio amplified by a conventional audio amplifier.
Conversely, if the output from the Shairport Sync device is passed through an AVR, then it could be late by comparison with audio amplified by a conventional audio amplifier.

The fix for this is to get Shairport Sync to compensate for delays by providing audio to the output device _slightly late_ or _slightly early_, so that when audio emerges from the amplifier, it is in exact synchrony with audio from the other devices.

The setting to look for is in the `general` section of the Shairport Sync configuration file and is called `audio_backend_latency_offset_in_seconds`. By default it is `0.0` seconds.

For example, to delay the output from the SPS device by 100 milliseconds (0.1 seconds), set the `audio_backend_latency_offset_in_seconds` to `0.1`, so that audio is provided to your output device 100 milliseconds later than nominal synchronisation time.
For example, to delay the output from the Shairport Sync device by 100 milliseconds (0.1 seconds), set the `audio_backend_latency_offset_in_seconds` to `0.1`, so that audio is provided to your output device 100 milliseconds later than nominal synchronisation time.

Similarly, to get the output from the SPS device 50 milliseconds (0.05 seconds) early, set the `audio_backend_latency_offset_in_seconds` to `-0.05`, so that audio is provided to your output device 50 milliseconds earlier than nominal synchronisation time.
Similarly, to get the output from the Shairport Sync device 50 milliseconds (0.05 seconds) early, set the `audio_backend_latency_offset_in_seconds` to `-0.05`, so that audio is provided to your output device 50 milliseconds earlier than nominal synchronisation time.

Latency adjustments should be small, not more than about ± 250 milliseconds.

Expand Down
Loading

0 comments on commit 6014351

Please sign in to comment.