Skip to content

Releases: sonn-audio/node-sendspin

v0.6.2

Choose a tag to compare

@rudyberends rudyberends released this 15 Sep 08:02
fix(controller): withhold commands a peer's library cannot name (v0.6.2)

`supported_commands` is a typed enum list on the far side, so a value the
client has never heard of does not degrade one feature — it invalidates the
whole `server/state`. An aiosendspin below 6.1.0 meets `seek`/`seek_relative`
that way: it drops the message, never starts the stream, and stays silent
while the server's log looks perfectly healthy.

The protocol cannot be asked. `client/hello` has no controller support object
and the core version has stayed 1 across every release, so a later enum entry
is indistinguishable from an original one. What a peer does tell us is which
library it is, in `device_info.software_version`, so filter there: a deny-list
of peers known to be blind, with everything unrecognised keeping the full set.

Filtering at the session rather than at the caller covers group members too,
which are sent the leader's payload verbatim. `seek_max_ms` goes out with
`seek`, and the tolerance is reported once through `onNoncompliance`.

v0.6.1

Choose a tag to compare

@rudyberends rudyberends released this 12 Aug 11:13
fix(client): receive JSON on an unencrypted connection (v0.6.1)

`handleWsMessage` decided text from binary with `typeof data === 'string'`, which is
never true: `ws` hands both kinds to the listener as a Buffer and tells them apart
with the `isBinary` argument, which was being ignored. So every JSON message on an
unencrypted connection went to the audio-chunk path and `connect()` timed out
waiting for a `server/hello` that had already arrived.

It went unnoticed because nothing in the app drives the client half, and the
encrypted path reads its bring-up frames through its own listener and its transport
frames as binary — so both of those worked. It surfaced the moment a plaintext
client was pointed at our own server.

v0.6.0

Choose a tag to compare

@rudyberends rudyberends released this 12 Aug 10:31
feat(client): speak Noise, and close the responder verification gap (…

v0.3.8

Choose a tag to compare

@rudyberends rudyberends released this 31 Jul 11:40
fix(player): honour the spec's static_delay direction, and stop dropp…

v0.3.7

Choose a tag to compare

@rudyberends rudyberends released this 28 Jul 16:08
feat(server): expose the player's declared format list (v0.3.7)

A host could read the negotiated stream format but not the list the client
declared in client/hello, so it had no way to check whether a format other
than the client's first preference was acceptable.

Hosts need the whole list to match the *source* instead of always taking
entry 0: a client that lists 48 kHz first but also declares 96 kHz can be
served a 24-bit/96 kHz file untouched, with no resampling on the way.

Returns copies, and an empty array when the client declared nothing.

v0.3.6

Choose a tag to compare

@rudyberends rudyberends released this 28 Jun 19:15

Re-scope to @sonn-audio (repository.url fixed for provenance).

v0.3.5

Choose a tag to compare

@rudyberends rudyberends released this 28 Jun 19:02

Move to the @sonn-audio npm scope (formerly @lox-audioserver/node-sendspin).

v0.3.4

Choose a tag to compare

@rudyberends rudyberends released this 24 Jun 14:21
feat(visualizer): add visualizer@v1 per-type wire support

The latest sendspin-cli advertises only visualizer@v1 and hides its panel
unless the server activates that exact role; we only offered the legacy
visualizer@_draft_r1, so the panel never showed. Add v1 alongside the draft.

- Roles.VISUALIZER_V1 negotiated; client/hello visualizer@v1_support parsed
  (types/rate_max/spectrum) and exposed via getVisualizerSupport()
- binary message types 18-21 (F_PEAK/SPECTRUM/PEAK/PITCH); LOUDNESS aliases 16
- sendVisualizerStreamStartV1 + per-type frame senders (loudness/spectrum/
  f_peak/peak/pitch/beat), packing [type:1][ts:8][payload] per the spec
- draft_r1 path left intact for esphome

This is the wire layer only; computing the frames (DSP) is the caller's job.
Bump 0.3.3 -> 0.3.4.

v0.3.2

Choose a tag to compare

@rudyberends rudyberends released this 04 Jun 16:25
fix(server): drop stale audio frame deferred across a stream clear/end

A frame deferred under send backpressure (5ms retry) could fire after a
stream/clear (seek) or stream/end, jumping the queue and injecting a stale
pre-seek frame into the post-clear stream. Bump a per-session streamGeneration
on clear/end and skip the deferred send if it changed — mirrors the reference
server's epoch invalidation. Bump version to 0.3.2.

v0.3.0

Choose a tag to compare

@rudyberends rudyberends released this 09 May 10:59
feat(player): add SET_STATIC_DELAY command for client-side static pla…