From 08eac90c9ad43bed14ffea2e5c9bd0426c9aa56c Mon Sep 17 00:00:00 2001 From: Chris Uthe Date: Wed, 16 Sep 2026 19:20:50 -0500 Subject: [PATCH 1/4] Bump to 0.2.0 and add its release notes --- CMakeLists.txt | 2 +- docs/release-notes/0.2.0.md | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 docs/release-notes/0.2.0.md diff --git a/CMakeLists.txt b/CMakeLists.txt index eb45561..9a59fe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(sendspin-cpp-cli - VERSION 0.1.6 + VERSION 0.2.0 DESCRIPTION "Headless CLI/daemon Sendspin audio player" HOMEPAGE_URL "https://github.com/Sendspin/sendspin-cpp" LANGUAGES CXX diff --git a/docs/release-notes/0.2.0.md b/docs/release-notes/0.2.0.md new file mode 100644 index 0000000..21d73e6 --- /dev/null +++ b/docs/release-notes/0.2.0.md @@ -0,0 +1,35 @@ +### Breaking changes + +- **`-s` no longer dials a typed-in address.** A host, `host:port`, or `ws://` URL passed + to `-s` — or set as `server =` in a config file — is now a parse error rather than a dial + target. The spec has exactly two ways to connect: the server discovers this client through + its `_sendspin._tcp` advertisement, or this client discovers a server on + `_sendspin-server._tcp` and connects to the address it advertised. Dialling a hand-entered + endpoint is neither, so it is gone. `-s mdns:[]` — discovery — is the only form left, + and it works exactly as before. An install still pointed at an address fails loudly at + startup instead of quietly changing how it connects; point the server at this player, or + switch to `-s mdns:`. (#56) + +### New features + +- **`--audio-format` takes an ordered list of preferred formats.** Pass a comma-separated + list, e.g. `--audio-format flac:48000:24:2,pcm:48000:24:2`, and those formats are offered + first in that order with the rest of the device-derived list still behind them — a + preference a server falls back from, not a restriction. The player refuses to start if the + advertised list cannot carry every entry, and an `opus` entry at anything but 48000/16 and + at most two channels is refused outright. (#57) + +### Fixed issues + +- **The systemd unit now allows `AF_NETLINK`,** so the MAC-derived client id is detected + under the shipped hardening rather than falling back to a random id. (#53) + +### Under the hood + +- **Re-pinned `sendspin-cpp` to v0.8.0** and adopted its `start()`/`stop()` lifecycle. (#62) +- **A `clang-format` CI gate and `scripts/format.sh`,** with comment guidelines in + `AGENTS.md`. (#61, #60) +- **The README is restructured** around what it is, how to run it, and how to contribute, and + the ARMv6 build leg moved into its own workflow. (#52, #51) + +**Full changelog:** https://github.com/@REPO@/compare/v0.1.6...@TAG@ From ab35530db67223668c2d55b762ae4a1c78771491 Mon Sep 17 00:00:00 2001 From: Chris Uthe Date: Wed, 16 Sep 2026 19:20:50 -0500 Subject: [PATCH 2/4] Update the roadmap scaffold summary for -s discovery-only The 'What the scaffold already does' line still said -s dials a literal address; #56 removed that. Item 5 and item 26 stay as the historical record. --- docs/ROADMAP.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 99dade2..09ed6fa 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -14,9 +14,9 @@ daemonization. - Boots a `SendspinClient` with the `player`, `metadata` and `controller` roles, starts its WebSocket server, pumps `client.loop()`, and shuts down cleanly on `SIGINT`/`SIGTERM`. - Speaks both of the protocol's connection modes, and keeps them exclusive as the spec - requires: it advertises `_sendspin._tcp` over mDNS by default, and any `-s` instead - makes it dial out — to an address, or to a server discovered on - `_sendspin-server._tcp` — retrying with a backoff until it answers (item 5). + requires: it advertises `_sendspin._tcp` over mDNS by default, and `-s mdns:` instead + discovers a server on `_sendspin-server._tcp` and dials it — retrying with a backoff + until it answers (item 5). A typed-in address is no longer accepted (item 26). - Defines the `AudioSink` seam (`src/audio_sink.h`) and plays real audio through it: auto-detected ALSA (item 2), PortAudio (item 3), PulseAudio (item 18) and PipeWire (item 19) backends, with the device-less null/stdout sink as the fallback, so the From 982b614eb4daf349d5d91d8d8ba616983632123d Mon Sep 17 00:00:00 2001 From: Chris Uthe Date: Wed, 16 Sep 2026 19:21:53 -0500 Subject: [PATCH 3/4] Correct the client-id fallback in the 0.2.0 notes --- docs/release-notes/0.2.0.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/0.2.0.md b/docs/release-notes/0.2.0.md index 21d73e6..c576ccb 100644 --- a/docs/release-notes/0.2.0.md +++ b/docs/release-notes/0.2.0.md @@ -22,7 +22,8 @@ ### Fixed issues - **The systemd unit now allows `AF_NETLINK`,** so the MAC-derived client id is detected - under the shipped hardening rather than falling back to a random id. (#53) + under the shipped hardening. Without it `getifaddrs()` fails and the player greets with an + empty `client_id`, which a server such as Music Assistant refuses. (#53) ### Under the hood From ac15ce8de4ca117afa1c5c50f046c54d0b660953 Mon Sep 17 00:00:00 2001 From: Chris Uthe Date: Wed, 16 Sep 2026 19:49:42 -0500 Subject: [PATCH 4/4] Add the sink outage-gap fix (#59) to the 0.2.0 notes --- docs/release-notes/0.2.0.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/release-notes/0.2.0.md b/docs/release-notes/0.2.0.md index c576ccb..4680a10 100644 --- a/docs/release-notes/0.2.0.md +++ b/docs/release-notes/0.2.0.md @@ -21,6 +21,11 @@ ### Fixed issues +- **A recovered audio device no longer jumps the playback clock.** While a sink had no live + stream, `write()` still reported the audio as consumed but nothing ever reported it as + played, so after recovery the playhead jumped ahead by the whole outage and sync cycled + between Lost and Regained. Fixed for the ALSA sink (#54, #55), then extended to the Pulse, + PortAudio and PipeWire sinks (#58, #59). - **The systemd unit now allows `AF_NETLINK`,** so the MAC-derived client id is detected under the shipped hardening. Without it `getifaddrs()` fails and the player greets with an empty `client_id`, which a server such as Music Assistant refuses. (#53)