dreamstack/examples/beats-viewer.ds
enzotar eb21aa2137 feat: beats viewer, score sounds, audio early-exit guards
- New beats-viewer.ds: step sequencer spectator via relay stream
- game-pong.ds: added score sound effects (220Hz/440Hz sawtooth)
- Runtime: _playTone skips when freq<=0, _playNoise skips when dur<=0
- All 47 examples compile, 136 tests pass
2026-02-27 10:05:32 -08:00

72 lines
2.3 KiB
Text

-- DreamStack Beats Viewer (Spectator)
-- Watches the step sequencer live via streaming relay.
-- Shows the beat grid state from a different browser tab.
--
-- Run with:
-- Tab 1: cargo run -p ds-stream (relay on :9100)
-- Tab 2: dreamstack dev examples/step-sequencer.ds (player)
-- Tab 3: dreamstack dev examples/beats-viewer.ds --port 3001 (viewer)
import { Badge } from "../registry/components/badge"
-- Connect to the beats stream
let beats = stream from "ws://localhost:9100/stream/beats"
view viewer = column [
text "👁️ Beats Spectator" { variant: "title" }
text "Watching the step sequencer live via relay" { variant: "subtitle" }
row [
Badge { label: "LIVE 🔴", variant: "error" }
Badge { label: "BPM: {beats.bpm}", variant: "info" }
Badge { label: "Step: {beats.step}", variant: "warning" }
]
-- Playhead indicator
row [
text " " { variant: "muted" }
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ->
text (if i == beats.step then "▼" else "·") { variant: "muted" }
]
-- Kick row (read-only)
row [
text "KICK " { variant: "caption" }
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ->
text (if beats.kick then "●" else "○") {
variant: (if i == beats.step then "warning" else "muted")
}
]
-- Snare row
row [
text "SNRE " { variant: "caption" }
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ->
text (if beats.snare then "●" else "○") {
variant: (if i == beats.step then "warning" else "muted")
}
]
-- HiHat row
row [
text "HHAT " { variant: "caption" }
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ->
text (if beats.hihat then "●" else "○") {
variant: (if i == beats.step then "warning" else "muted")
}
]
-- Bass row
row [
text "BASS " { variant: "caption" }
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] ->
text (if beats.bass then "●" else "○") {
variant: (if i == beats.step then "warning" else "muted")
}
]
when beats.playing -> text "▶ Playing" { variant: "muted" }
else -> text "⏸ Paused" { variant: "muted" }
text "View-only • beat pattern received via relay" { variant: "muted" }
]