Add ohm, an OpenHome Songcast sender audio backend
Set variables for a Docker build (used by another workflow). / Set variables required for docker build. (push) Successful in 28s
Build and conditionally push docker image / docker-vars (push) Successful in 28s
Build and conditionally push docker image / Build and conditionally push docker image (SHAIRPORT_SYNC_BRANCH=. NQPTP_BRANCH=${{ needs.docker-vars.outputs.nqptp_branch }} , ./docker/Dockerfile, main) (push) Failing after 31m53s
Build and conditionally push docker image / Build and conditionally push docker image (SHAIRPORT_SYNC_BRANCH=. , ./docker/classic/Dockerfile, classic) (push) Failing after 32m4s

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.
This commit is contained in:
2026-08-28 23:48:23 +02:00
parent fadd43d06e
commit 73264f4534
7 changed files with 1580 additions and 2 deletions
+4 -1
View File
@@ -1,4 +1,7 @@
.github .github
documents documents
docker/Dockerfile docker/Dockerfile
docker/classic/Dockerfile docker/classic/Dockerfile
reference
ohm.txt
out-ohm
+4
View File
@@ -112,6 +112,10 @@ if USE_DUMMY
shairport_sync_SOURCES += audio_dummy.c shairport_sync_SOURCES += audio_dummy.c
endif endif
if USE_OHM
shairport_sync_SOURCES += audio_ohm.c
endif
if USE_AO if USE_AO
shairport_sync_SOURCES += audio_ao.c shairport_sync_SOURCES += audio_ao.c
endif endif
+6
View File
@@ -62,6 +62,9 @@ extern audio_output audio_pipe;
#ifdef CONFIG_STDOUT #ifdef CONFIG_STDOUT
extern audio_output audio_stdout; extern audio_output audio_stdout;
#endif #endif
#ifdef CONFIG_OHM
extern audio_output audio_ohm;
#endif
static audio_output *outputs[] = { static audio_output *outputs[] = {
#ifdef CONFIG_ALSA #ifdef CONFIG_ALSA
@@ -93,6 +96,9 @@ static audio_output *outputs[] = {
#endif #endif
#ifdef CONFIG_DUMMY #ifdef CONFIG_DUMMY
&audio_dummy, &audio_dummy,
#endif
#ifdef CONFIG_OHM
&audio_ohm,
#endif #endif
NULL}; NULL};
+1493
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -98,6 +98,12 @@ if test "x$with_pipe" = "xyes" ; then
fi fi
AM_CONDITIONAL([USE_PIPE], [test "x$with_pipe" = "xyes" ]) AM_CONDITIONAL([USE_PIPE], [test "x$with_pipe" = "xyes" ])
AC_ARG_WITH([ohm],[AS_HELP_STRING([--with-ohm],[build the OpenHome Songcast OHM/OHU unicast sender audio backend into Shairport Sync])])
if test "x$with_ohm" = "xyes" ; then
AC_DEFINE([CONFIG_OHM], 1, [Include the OpenHome Songcast OHM/OHU unicast sender audio backend.])
fi
AM_CONDITIONAL([USE_OHM], [test "x$with_ohm" = "xyes"])
# Check to see if we should include the System V initscript # Check to see if we should include the System V initscript
AC_ARG_WITH([systemv-startup],[AS_HELP_STRING([--with-systemv-startup],[install a System V startup script during a make install])]) AC_ARG_WITH([systemv-startup],[AS_HELP_STRING([--with-systemv-startup],[install a System V startup script during a make install])])
+66
View File
@@ -0,0 +1,66 @@
# Minimal cross-build of shairport-sync with the OHM Songcast sender backend,
# for linux/arm64 (Raspberry Pi OS aarch64). Produces a glibc binary compatible
# with Debian bullseye (glibc 2.31) and later (e.g. bookworm).
#
# Usage from the repo root:
# docker buildx build --platform linux/arm64 --target binary \
# -f docker/Dockerfile.ohm --output type=local,dest=./out-ohm .
#
# Then copy ./out-ohm/shairport-sync to the Pi.
#
# FFmpeg is taken from Debian packages (libavcodec-dev etc.) rather than built
# from source, to keep the cross-build fast under emulation.
ARG DEBIAN_VERSION=bullseye
FROM --platform=linux/arm64 debian:${DEBIAN_VERSION} AS builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
autoconf \
automake \
libtool \
pkg-config \
git \
ca-certificates \
xxd \
libasound2-dev \
libplist-dev \
libplist-utils \
libssl-dev \
libsodium-dev \
libgcrypt-dev \
uuid-dev \
libavcodec-dev \
libavformat-dev \
libswresample-dev \
libavutil-dev \
libavahi-client-dev \
avahi-daemon \
libdbus-1-dev \
libglib2.0-dev \
libconfig-dev \
libpopt-dev \
libsndfile-dev \
libsoxr-dev \
xmltoman \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /shairport-sync
COPY . .
WORKDIR /shairport-sync/build
RUN autoreconf -i ../
RUN ../configure --sysconfdir=/etc --with-alsa \
--with-avahi --with-ssl=openssl \
--with-airplay-2 --with-ffmpeg --with-metadata \
--with-ohm --with-dummy --with-pipe --with-stdout \
--with-dbus-interface --with-mpris-interface \
--with-convolution --with-soxr
RUN make -j"$(nproc)"
# Target that yields just the binary on the host filesystem via --output.
FROM --platform=linux/arm64 scratch AS binary
COPY --from=builder /shairport-sync/build/shairport-sync /shairport-sync
+1 -1
View File
@@ -4,7 +4,7 @@
#include "rtsp.h" #include "rtsp.h"
#include <pthread.h> #include <pthread.h>
#define number_of_watchers 2 #define number_of_watchers 3
typedef enum { typedef enum {
PS_NOT_AVAILABLE = 0, PS_NOT_AVAILABLE = 0,