Step sequencer: 4 instruments × 8 steps, timer-driven playhead, toggleable pads, BPM controls with streaming. 75 lines of .ds code. Parser fixes: - UI elements checked before LParen (button (if ...) is element, not call) - Element args support parenthesized expressions: button (if cond ...) - StringInterp recognized as valid string start in parse_primary/parse_element Codegen fixes: - emit_expr checks local_vars: loop var i emits 'i' not 'i.value' - Array index mutations re-trigger signal: pads.value = [...pads.value] 110 tests, 0 failures.
72 lines
1.7 KiB
Text
72 lines
1.7 KiB
Text
-- DreamStack Step Sequencer
|
||
-- Collaborative beat grid: two tabs, same pads, real-time sync
|
||
|
||
let bpm = 120
|
||
let step = 0
|
||
|
||
-- 4 instruments × 8 steps = 32 pads (flat array, index with row*8+col)
|
||
let pads = [0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0]
|
||
|
||
-- Playhead advances every beat
|
||
every (60000 / bpm / 2) -> step = (step + 1) % 8
|
||
|
||
-- Stream for multiplayer
|
||
stream sequencer on "ws://localhost:9100/source/beats" { mode: signal }
|
||
|
||
view sequencer =
|
||
column [
|
||
text "DreamStack Beats"
|
||
text "BPM: {bpm}"
|
||
|
||
-- Kick (pads 0-7)
|
||
text "Kick"
|
||
row [
|
||
for i in [0, 1, 2, 3, 4, 5, 6, 7] ->
|
||
button (if pads[i] then "●" else "○") {
|
||
click: pads[i] = if pads[i] then 0 else 1
|
||
}
|
||
]
|
||
|
||
-- Snare (pads 8-15)
|
||
text "Snare"
|
||
row [
|
||
for i in [8, 9, 10, 11, 12, 13, 14, 15] ->
|
||
button (if pads[i] then "●" else "○") {
|
||
click: pads[i] = if pads[i] then 0 else 1
|
||
}
|
||
]
|
||
|
||
-- Hi-hat (pads 16-23)
|
||
text "HiHat"
|
||
row [
|
||
for i in [16, 17, 18, 19, 20, 21, 22, 23] ->
|
||
button (if pads[i] then "●" else "○") {
|
||
click: pads[i] = if pads[i] then 0 else 1
|
||
}
|
||
]
|
||
|
||
-- Bass (pads 24-31)
|
||
text "Bass"
|
||
row [
|
||
for i in [24, 25, 26, 27, 28, 29, 30, 31] ->
|
||
button (if pads[i] then "●" else "○") {
|
||
click: pads[i] = if pads[i] then 0 else 1
|
||
}
|
||
]
|
||
|
||
-- Playhead indicator
|
||
row [
|
||
for i in [0, 1, 2, 3, 4, 5, 6, 7] ->
|
||
text (if i == step then "▼" else "·")
|
||
]
|
||
|
||
-- BPM controls
|
||
row [
|
||
button "−10" { click: bpm -= 10 }
|
||
text "{bpm}"
|
||
button "+10" { click: bpm += 10 }
|
||
]
|
||
]
|