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 1s
Build and conditionally push docker image / docker-vars (push) Successful in 2s
Build and conditionally push docker image / Build and conditionally push docker image (SHAIRPORT_SYNC_BRANCH=.
, ./docker/classic/Dockerfile, classic) (push) Failing after 31m52s
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 31m49s
Set variables for a Docker build (used by another workflow). / Set variables required for docker build. (push) Successful in 1s
Build and conditionally push docker image / docker-vars (push) Successful in 2s
Build and conditionally push docker image / Build and conditionally push docker image (SHAIRPORT_SYNC_BRANCH=.
, ./docker/classic/Dockerfile, classic) (push) Failing after 31m52s
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 31m49s
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.
This commit is contained in:
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* OpenHome receiver control for the ohm audio backend.
|
||||
*
|
||||
* This file is part of Shairport Sync.
|
||||
* Copyright (c) Nils Schneider 2026
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* XML-escape src into dst (NUL-terminated). Returns chars written (excluding NUL). */
|
||||
size_t ohm_xml_escape(char *dst, size_t dst_cap, const char *src);
|
||||
|
||||
/* The backend declares volume as attenuation -OHM_UPNP_VOLUME_RANGE_CDB..0
|
||||
* (dB * 100); shairport stretches the AirPlay slider over exactly this range. */
|
||||
#define OHM_UPNP_VOLUME_RANGE_CDB 6000
|
||||
|
||||
typedef struct {
|
||||
const char *receiver_name; /* friendly name to match; NULL disables the module */
|
||||
const char *interface_ip;
|
||||
const char *display_name;
|
||||
int standby_minutes; /* 0 = never */
|
||||
int ohu_port;
|
||||
} ohm_upnp_config_t;
|
||||
|
||||
/* Strings are copied. */
|
||||
void ohm_upnp_configure(const ohm_upnp_config_t *config);
|
||||
int ohm_upnp_enabled(void);
|
||||
|
||||
/* Callback side: cheap, thread-safe, never block. */
|
||||
void ohm_upnp_session_begin(void);
|
||||
void ohm_upnp_session_end(void);
|
||||
void ohm_upnp_set_volume(long vol_cdb); /* dB * 100, <= 0 */
|
||||
|
||||
/* Does the network work (SSDP discovery, SOAP); call periodically from one
|
||||
* thread. */
|
||||
void ohm_upnp_tick(void);
|
||||
|
||||
void ohm_upnp_deinit(void);
|
||||
Reference in New Issue
Block a user