Skip to content

fix(viz): sakura + heartbeat AGC; remove firework#64

Merged
vxcozy merged 1 commit into
mainfrom
fix/viz-sakura-heartbeat-remove-firework
Apr 19, 2026
Merged

fix(viz): sakura + heartbeat AGC; remove firework#64
vxcozy merged 1 commit into
mainfrom
fix/viz-sakura-heartbeat-remove-firework

Conversation

@vxcozy
Copy link
Copy Markdown
Owner

@vxcozy vxcozy commented Apr 19, 2026

Summary

  • sakura — route petal-spawn intensity through SpectrumScaler::normalise + stochastic fractional-carry so quiet volumes still precipitate.
  • heartbeat — new sibling SampleScaler (sample-domain AGC, mirrors the SpectrumScaler attack/release philosophy) lifts the ECG trace off the baseline at typical listening volumes.
  • firework — full deletion; visualiser catalogue drops 23 → 22. Module, enum variant, parse arms, carousel registration, pane_mode entry, fuzzy/command_bar test catalogues, README family list, and the cli.md reference row all removed.

Why

Live-testing v1.2.0 surfaced three viz bugs in the same class as CLI-89: amplitude-scaling math tuned for ≈1.0 signals silently fails at typical listening volumes (peak_sample ≈ 0.05–0.15).

Viz Symptom Root cause
sakura black screen spawn_count = (energy * 3.0) as usize truncates to 0 until energy ≥ 0.33
heartbeat flat line raw sample amplitudes map directly to Y-pixels, tiny samples = 1-pixel trace
firework black screen delta > TRANSIENT_THRESHOLD never trips at normal volume

The sakura and heartbeat fixes extend the CLI-89 pattern (PR #57): put the input on an envelope-follower AGC so typical listening volume reads as full-scale visual amplitude, with fast attack + slow release so transients pop and the gain ceiling doesn't strobe on brief dips.

SampleScaler is a bipolar-sample sibling to SpectrumScalerSpectrumScaler does log/dB compression on magnitudes (non-negative), which doesn't cleanly map to [-1, 1] PCM samples; the sample-domain tracker keeps sign and tracks |sample| peak directly.

Firework's transient detector was the wrong reactive primitive for ambient audio — it required a sharp spike in already-smoothed energy, which essentially never occurs outside contrived test fixtures. Rather than re-tune (and introduce another ghost viz in the carousel), removed entirely.

Test plan

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --all-features
  • new unit tests:
    • scaling::sample_scaler_quiet_signal_fills_majority_of_range
    • scaling::sample_scaler_preserves_sign
    • scaling::sample_scaler_loud_transient_clamps_without_overshoot
    • scaling::sample_scaler_silence_does_not_auto_gain
    • scaling::sample_scaler_attack_faster_than_release
    • sakura::quiet_listening_volume_still_spawns_petals (≥10 petals over 30 frames at ~0.05 peak)
    • heartbeat::quiet_listening_volume_lifts_trace_off_baseline (≥20% of pane height)
    • heartbeat::loud_volume_saturates_without_overshoot (≥80% peak, clamped ≤1.0)
  • manual: launch clitunes, press p to cycle to sakura, verify petals rain continuously at normal volume
  • manual: cycle to heartbeat, verify the ECG trace sweeps across the pane instead of sitting flat on the baseline
  • manual: :viz firework is rejected (name no longer in the catalogue)

Live testing after v1.2.0 surfaced three viz bugs in the same class as
CLI-89: amplitude-scaling math tuned for ≈1.0 signals fails at typical
listening volumes (peak_sample ≈ 0.05–0.15).

sakura — black screen until energy ≥ 0.33. `spawn_count = (energy *
3.0) as usize` truncated to zero at quiet volume. Routed spawn
intensity through `SpectrumScaler::normalise` so intensity is in
per-frame-peak-normalised units, then added a stochastic carry on the
fractional remainder so a normalised 0.05 still yields ≥1 petal
occasionally (continuous precipitation at quiet volume, dense at
loud). EnergyTracker dropped — it had no other users in this viz.

heartbeat — flat line. Raw bipolar samples at ~0.05 peak multiplied
by `sample * |sample|` compressed to ~0.0025, collapsing the Y
excursion to one pixel above the baseline. Added a sibling
`SampleScaler` (envelope-follower AGC over `|sample|`, mirrors the
SpectrumScaler attack/release philosophy) and normalise each sample
before the `n * |n|` spike shape. Trace now lifts off the baseline
at any reasonable listening volume and clamps cleanly on loud
transients.

firework — black screen. Transient detector (`delta >
TRANSIENT_THRESHOLD = 0.12`) never tripped at normal volume, so no
fireworks ever launched. Full deletion: module, re-export, enum
variant, parse/as_str arms, catalogue entry (23 → 22), pane_mode
registration, fuzzy/command_bar test catalogues, README family list,
and the cli.md reference row. Historical CHANGELOG entries left
intact — they describe prior releases that shipped firework.

Closes clitunes-wwv / CLI-97
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vxcozy vxcozy merged commit e74b7d7 into main Apr 19, 2026
12 checks passed
@vxcozy vxcozy deleted the fix/viz-sakura-heartbeat-remove-firework branch April 19, 2026 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant