Skip to content

v0.1.0 beta.1#29

Open
thomaseleff wants to merge 74 commits into
mainfrom
v0.1.0-beta.1
Open

v0.1.0 beta.1#29
thomaseleff wants to merge 74 commits into
mainfrom
v0.1.0-beta.1

Conversation

@thomaseleff

Copy link
Copy Markdown
Collaborator

No description provided.

thomaseleff and others added 29 commits June 22, 2026 15:55
Set silence_threshold and silence_timeout to null and
stop_on_rate_change to false so the ALSA device stays open
continuously. Closing the device after 10s of silence causes
the HDMI sink to de-clock, resulting in audio dropout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Append hdmi_force_hotplug, hdmi_drive, and related overlays to
/boot/firmware/config.txt to stabilise the HDMI audio output at
boot. Add a camilladsp-hdmi-wait.path unit that holds CamillaDSP
until /dev/snd/pcmC0D0p exists so it never races the HDMI device.
camilladsp.service is no longer directly enabled; the path unit
activates it once the device node appears.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Write /etc/profile.d/50-audera-banner.sh on both player and streamer
to display the Audera logo and remind operators to use nmcli and
/boot/firmware/config.txt instead of dietpi-config for WiFi and
audio hardware management.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add tests/docker/camilladsp/ with a Dockerfile (Dummy ALSA backend,
port 1234) and a minimal config.yml. Replace the in-process websocket
mock fixtures with a session-scoped camilladsp_container fixture that
waits for the real binary to accept WebSocket connections. Pure unit
tests (percent_to_db, db_to_percent, error path) no longer require a
live connection and use a locally constructed client instead. Update
tests/AGENTS.md with the Docker build prerequisite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the pre-built image approach with DockerImage so the fixture
is self-contained. Removes the manual docker build step from CI and
the pre-build instruction from tests/AGENTS.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the inline bash-c install command with a proper Dockerfile
and entrypoint script under tests/docker/snapserver/, matching the
CamillaDSP testcontainer pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirror the setup.sh approach: wget to /tmp first, then tar, matching
the pattern used in the player and streamer provision scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Release assets use 'amd64' not 'x86_64'. test_error_response_raises
needs a live CamillaDSP instance to return an error response — connect
to localhost:0 raises a connection error, not RuntimeError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… responses

Bind CamillaDSP WebSocket to 0.0.0.0 so Docker port forwarding can reach it
(default 127.0.0.1 loopback is unreachable via bridge NAT). Fix _call to detect
{'Invalid': ...} error responses for unknown commands. Fix test_set_config to
send a complete config with the devices section and assert only the changed keys.
Harden _wait_for_websocket against Windows named pipe timeouts on get_logs().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vc4-fkms-v3d never creates the vc4-hdmi platform device that
snd_soc_hdmi_codec needs, so no HDMI ALSA soundcard ever appeared.
Switch to vc4-kms-v3d (confirmed working across Zero 2W, Pi 4, and
Pi 5) and add vc4.force_hotplug=3 so HDMI comes up even headless.

Extract the config-injection logic into a shared os/dietpi/lib/config.sh,
fetched by both setup.sh scripts the same way they already fetch
themselves, and make each setting idempotent per-key (replaces an
active or commented-out line, appends if absent) instead of relying
on a block-comment header.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rvice directly

The path unit was the only thing triggering CamillaDSP at boot since the
service itself was never enabled. Restart=always already retries on
failure, so enabling the service directly and letting it fail-and-retry
until the sound card is ready achieves the same result without a
hardcoded /dev/snd/pcmC0D0p path that only matched the DigiAMP+ default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
setup.sh unconditionally wrote dtoverlay=vc4-kms-v3d on every
provision/re-provision run, silently overwriting the dtoverlay DietPi wrote
at flash-time for non-HDMI hardware (e.g. rpi-digiampplus). Add an optional
--audio-device flag to provision.sh (hdmi, digiamp-plus, dac-plus,
hifiberry-dac-plus) that is passed through to setup.sh; when omitted, the
existing dtoverlay is left untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Player and streamer setup.sh scripts duplicated root check, ALSA loopback
setup, dtoverlay config, CamillaDSP install, uv/audera CLI install,
ifupdown purge, NetworkManager setup, WiFi power-save, the ASCII logo,
boot banner, and camilladsp.service unit. Move these into lib/config.sh
and a new lib/common.sh so future fixes only need to land in one place.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Introduces the catalog pattern (audera/ui/features.py) so streamer-dashboard
features can offer 2-3 user-selectable UX options instead of one guessed
default. Adds the Settings.features persistence field (round-trips through
the existing DAL with no code changes), ADR 004 documenting the design
decisions, and DAL/catalog tests. No tab-rendering changes yet -- those land
in WS2/WS3/WS4.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
)

Settings tab now renders one auto-saving toggle group per registered
audera.ui.features entry (Player Selection, Volume) instead of the
PlexAmp/Snapserver host inputs and manual Save button. Host fields stay
on Settings for client construction but are now env-var only.

_load_settings() switches to settings_dal.get_or_create() seeded with
features.default_selections(), so settings.json exists with resolved
flags from the first dashboard load.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… (WS3, #42)

Reads the player_selection feature flag to switch Snapcast client cards
between the default mute checkbox and a header enable/disable switch that
drives client.muted directly, collapsing muted clients to a minimized
single-line card.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wires the previously inert 'volume' feature flag into the Players tab:
adds a volume_up icon and live NN%/-N.N dB label to the existing
percent slider, and a new dB-scaled slider (routed through
CamillaDSPClient.set_volume) when the 'db' option is selected.
DSPConfig.volume remains the canonical persisted percent value in
both modes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…R 004

Adds explicit guidance to audera/ui/AGENTS.md and ADR 004 that agents
implementing UI features should propose/ask about feature-flag
optionality by default rather than hard-coding a single UX. Also
reflows ADR 004's paragraphs to one line each, matching the
line-per-paragraph convention used by ADRs 001-003.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ge (#42)

Players tab: Mute checkbox moves out of the volume row (which wrapped on
narrow viewports) into the card header, and both percent/dB sliders now
grow to fill the row instead of a fixed w-48.

CamillaDSPClient: volume is now attenuation-only, mapping 0-100% onto a
fixed -80..0 dB range (MIN_DB/MAX_DB) instead of deriving dB from percent
and separately clamping the top to a self-imposed -3.0 dB, which squeezed
the practical 1-100% range into the top ~17dB of an 87dB-wide slider.

Clip protection for the Loudness filter's own automatic boost moves from
that fader clamp to a dedicated Gain preamp-attenuation filter, inserted
into the pipeline only while Loudness is enabled.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Players-tab dB experience had three defects surfaced on a re-provisioned
streamer:

- dB slider re-seeded at a different spot after an edit, because
  db_to_percent truncated to int and DSPConfig.volume was an int, so a dB
  edit round-tripped lossily.
- A normal mid-range dB edit silently muted the client: db_to_percent
  truncated anything below ~-40.5 dB to 0, and the persist path muted
  whenever percent == 0.

Fixes:
- db_to_percent returns a precise float (0.0 only at/below the floor);
  DSPConfig.volume is now a float so dB edits round-trip without drift.
- MIN_DB -80.0 -> -50.0 to match CamillaGUI's default slider range.
- Mute is anchored at the slider floor (db <= MIN_DB / percent <= 0), not
  on lossy zero-rounding.
- Both slider seeds are step-aligned so the periodic refresh does not fire
  a phantom update:model-value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…'t move (#42)

The dB experience used a dB-scaled slider (min=MIN_DB, max=MAX_DB), so the
handle jumped when toggling modes: the same volume sits at percent/100 of the
track in percent mode but at (db-MIN_DB)/(MAX_DB-MIN_DB) in dB mode.

Per the agreed design, the slider is now ALWAYS a percent (0-100) control; the
'volume' feature selection only swaps the value label (NN% vs
percent_to_db(value) as -N.N dB). The handle position is therefore identical
across modes, and both modes drive CamillaDSP through set_percent_volume with
DSPConfig.volume (percent) as the single canonical value. Mute stays anchored
at the floor (percent <= 0, shown as MIN_DB in dB mode).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Give the dB value label a fixed width + right-align so the volume
  slider length stays constant as the text changes digit count
  (e.g. -9.0 dB -> -10.0 dB) instead of shifting the handle.
- In the disabled experience, gray out a disabled player's name and
  disable its settings icon to reinforce the "disabled" intent.
- Name flag-resolution locals after their FF_* constant so every
  flag-gated UI branch is obvious; record the convention as decision 7
  in ADR 004.
- Add an Architecture decisions section to AGENTS.md pointing agents at
  docs/adrs/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
)

HDMI sinks reject S32LE playback (silence/dropouts) and ignore the legacy
hdmi_* config.txt settings under full KMS. Fix both in provisioning:

- CamillaDSP playback format is now a `conf --playback-format` flag
  (default S32LE); provisioning passes S16LE for `--audio-device hdmi`
  via a `camilladsp_playback_format` helper. Capture stays S32LE to match
  Snapclient's 32-bit loopback. No quality loss: the pipeline ceiling is
  already 16-bit/48 kHz (ADR 002), so the 32-bit path is zero-padding.
- `dtoverlay=vc4-kms-v3d` -> `vc4-fkms-v3d` so the hdmi_* settings apply.

To avoid a split architecture, all bundled configs move from data files
(`audera/conf/`) into render functions in `audera/cli/conf.py`, the single
source of truth. snapserver.conf / asound.conf are reproduced byte-for-byte
(verified against HEAD); camilladsp.yml is parameterized on playback format.

The Docker snapserver fixture now renders the config to a temp file, and the
conf tests assert real render output (no more importlib mocking).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix: decouple from DietPi, HDMI stability, real CamillaDSP tests
@thomaseleff thomaseleff changed the title V0.1.0 beta.1 v0.1.0 beta.1 Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request v0.1.0-beta.1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant