Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4d8ee6b
feat: add expressive piano MIDI interpreter
G-4-R-Y Sep 22, 2026
56311e1
feat: add BPM quantization and cue loop recording
G-4-R-Y Sep 22, 2026
8a1e531
feat: add local live performance dashboard and OSC state feedback
G-4-R-Y Sep 22, 2026
c1401e8
fix: keep piano interpreter independent from control bus module
G-4-R-Y Sep 22, 2026
ee23408
feat: add expressive piano mode to MIDI input
G-4-R-Y Sep 22, 2026
18d1ca0
feat: integrate piano expression quantized cues loops and live dashboard
G-4-R-Y Sep 22, 2026
52e638d
feat: add optional Ableton Link beat clock adapter
G-4-R-Y Sep 22, 2026
9025a82
build: add opt-in Ableton Link extra
G-4-R-Y Sep 22, 2026
f8f8269
feat: show performance clock source in live dashboard
G-4-R-Y Sep 22, 2026
8e2e093
feat: let Performance Director quantize from optional Ableton Link
G-4-R-Y Sep 22, 2026
a9b1172
feat: expose piano quantization loops dashboard and Link controls in UI
G-4-R-Y Sep 22, 2026
eafc6d2
test: cover expressive piano MIDI behavior
G-4-R-Y Sep 22, 2026
68ee357
test: cover beat bar quantization and cue looping
G-4-R-Y Sep 22, 2026
5d5d862
feat: add CC-only MIDI state feedback and loop shortcuts
G-4-R-Y Sep 22, 2026
d6cd23c
feat: wire optional MIDI CC state feedback into Performance Director
G-4-R-Y Sep 22, 2026
048892e
feat: expose optional MIDI state feedback in UI
G-4-R-Y Sep 22, 2026
dad050c
refactor: simplify quantized event queue draining
G-4-R-Y Sep 22, 2026
1c32c9d
test: cover piano MIDI mode and CC-only state feedback
G-4-R-Y Sep 22, 2026
a8b1901
test: include piano timing and dashboard modules in frozen self-test
G-4-R-Y Sep 22, 2026
3e3d239
docs: add piano mode quantization loops dashboard feedback and Link
G-4-R-Y Sep 22, 2026
341a1ba
docs: surface piano performance console features
G-4-R-Y Sep 22, 2026
87b85b6
docs: track piano mode and synchronized live performance features
G-4-R-Y Sep 22, 2026
32b7fb4
feat: add one-click Piano Performance feature
G-4-R-Y Sep 22, 2026
8e7f2f1
test: cover one-click Piano Performance registry feature
G-4-R-Y Sep 22, 2026
99a3a1f
test: validate Piano Performance feature in frozen self-test
G-4-R-Y Sep 22, 2026
3d5a38c
test: cover Link clock interpolation and live state telemetry
G-4-R-Y Sep 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ See [`ROADMAP.md`](ROADMAP.md) for detailed deliverables, exit criteria, extensi
- unified Performance Director combining musical section/phrase tracking, Shader Performance Deck cues, persistent GPU particle choreography, and one shared MADNESS macro
- timed / musical / hybrid audiovisual journeys with drop overrides and smooth shader/particle cue morphing
- live Performance Director control via keyboard, MIDI and localhost OSC, with persistent A/B snapshots and user journeys
- expressive piano MIDI mode: velocity/pitch/chords/polyphony/sustain directly shape shader + particle behavior
- beat/bar-quantized live cue launches, musical cue-loop recording, local browser performance dashboard, OSC/MIDI state feedback, and opt-in Ableton Link clocking
- modular realtime runtime loop
- OpenCV fullscreen sink
- Spout adapter interface + diagnostics on Windows
Expand Down
122 changes: 121 additions & 1 deletion configs/features.d/performance_director.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id = "performance_director"
name = "Performance Director / Shader + Particles"
category = "Visual Madness"
description = "Unified audiovisual conductor with live keyboard, OSC and MIDI control. Music-aware section/phrase tracking chooses coordinated shader presets and GPU particle choreography while one smoothed MADNESS macro drives chaos, palette drift, scene morphing, particle density/turbulence/bloom, vector-field force, and layer composition. Supports persistent A/B snapshots and user journeys. F11 toggles fullscreen."
description = "Unified audiovisual conductor with expressive piano mode, live browser dashboard, keyboard/OSC/MIDI control, beat/bar-quantized launches, cue-loop recording, optional Ableton Link clocking, OSC state feedback, persistent A/B snapshots and user journeys. Piano velocity, pitch, chord tension, note density/spread and sustain shape shaders and GPU particles continuously. F11 toggles fullscreen."
command = ["python", "experiments/33_performance_director.py"]
fullscreen = true
requires_modules = ["soundcard", "moderngl"]
Expand Down Expand Up @@ -51,6 +51,35 @@ type = "bool"
default = false
group = "Live Control"

[[feature.param]]
key = "midi_mode"
flag = "--midi-mode"
label = "MIDI performance mode"
type = "choice"
default = "controls"
choices = ["controls", "piano"]
group = "Live Control"
help = "Piano mode uses musical note velocity, pitch, density, register spread, chord tension and pedals as continuous visual expression instead of treating every note as a button."

[[feature.param]]
key = "piano_hot_cues"
flag = "--piano-hot-cues"
label = "Low-key piano hot-cue zone"
type = "bool"
default = false
group = "Live Control"
help = "Optional. Disabled by default so the full keyboard remains playable."

[[feature.param]]
key = "piano_cue_note_base"
flag = "--piano-cue-note-base"
label = "Piano cue zone base MIDI note"
type = "int"
default = 21
min = 0
max = 120
group = "Live Control"

[[feature.param]]
key = "midi_device"
flag = "--midi-device"
Expand Down Expand Up @@ -79,6 +108,33 @@ min = 0
max = 115
group = "Live Control"

[[feature.param]]
key = "midi_output"
flag = "--midi-output"
label = "Enable MIDI state feedback"
type = "bool"
default = false
group = "Live Control"
help = "CC-only feedback; no note messages are sent. Disabled by default to avoid changing a piano's internal controls unexpectedly."

[[feature.param]]
key = "midi_output_device"
flag = "--midi-output-device"
label = "MIDI output device substring"
type = "text"
default = ""
group = "Live Control"

[[feature.param]]
key = "midi_feedback_cc_base"
flag = "--midi-feedback-cc-base"
label = "MIDI feedback CC base"
type = "int"
default = 20
min = 0
max = 123
group = "Live Control"

[[feature.param]]
key = "user_journey"
flag = "--user-journey"
Expand All @@ -95,6 +151,70 @@ type = "text"
default = ""
group = "Live Control"

[[feature.param]]
key = "quantize"
flag = "--quantize"
label = "Live cue quantization"
type = "choice"
default = "beat"
choices = ["off", "beat", "bar"]
group = "Live Control"

[[feature.param]]
key = "dashboard_host"
flag = "--dashboard-host"
label = "Dashboard bind host"
type = "text"
default = "127.0.0.1"
group = "Live Control"

[[feature.param]]
key = "dashboard_port"
flag = "--dashboard-port"
label = "Browser dashboard port (0 = off)"
type = "int"
default = 8765
min = 0
max = 65535
group = "Live Control"

[[feature.param]]
key = "osc_state_host"
flag = "--osc-state-host"
label = "OSC state target host"
type = "text"
default = "127.0.0.1"
group = "Live Control"

[[feature.param]]
key = "osc_state_port"
flag = "--osc-state-port"
label = "OSC state target port (0 = off)"
type = "int"
default = 9001
min = 0
max = 65535
group = "Live Control"

[[feature.param]]
key = "ableton_link"
flag = "--ableton-link"
label = "Use Ableton Link clock"
type = "bool"
default = false
group = "Live Control"
help = "Optional GPLv3+ aalink integration. Install the link extra separately; not bundled into default desktop builds."

[[feature.param]]
key = "link_tempo"
flag = "--link-tempo"
label = "Initial Link tempo"
type = "float"
default = 120.0
min = 30.0
max = 300.0
group = "Live Control"

[[feature.param]]
key = "state_file"
flag = "--state-file"
Expand Down
169 changes: 169 additions & 0 deletions configs/features.d/piano_performance.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
[[feature]]
id = "piano_performance"
name = "Piano Performance / MIDI Keyboard"
category = "Visual Madness"
description = "Play the projection system from a MIDI piano. Pitch, velocity, chord tension, polyphony, register spread and pedals continuously shape Shader Performance Deck + GPU particles. Cue changes are beat-quantized by default; browser dashboard, OSC and cue-loop recording remain active. The low-key cue zone is optional so the full keyboard stays musical."
command = ["python", "experiments/33_performance_director.py", "--midi", "--midi-mode", "piano"]
fullscreen = true
requires_modules = ["soundcard", "moderngl", "mido", "rtmidi"]

[[feature.param]]
key = "midi_device"
flag = "--midi-device"
label = "Piano / MIDI input substring"
type = "text"
default = ""
group = "System & Input"
help = "Leave blank to use the first MIDI input. Use --list-midi from the CLI if the piano is not selected automatically."

[[feature.param]]
key = "source"
flag = "--source"
label = "Music audio source"
type = "choice"
default = "system"
choices = ["system", "mic"]
group = "System & Input"

[[feature.param]]
key = "device"
flag = "--device"
label = "Audio device name/id (optional)"
type = "text"
default = ""
group = "System & Input"

[[feature.param]]
key = "journey"
flag = "--journey"
label = "Performance journey"
type = "choice"
default = "liquid_arc"
choices = ["liquid_arc", "neon_ritual", "cosmic_rave"]
group = "Design Customization"

[[feature.param]]
key = "madness"
flag = "--madness"
label = "Base MADNESS"
type = "float"
default = 0.42
min = 0.0
max = 1.0
group = "Behavior & Reactivity"

[[feature.param]]
key = "quantize"
flag = "--quantize"
label = "Cue quantization"
type = "choice"
default = "beat"
choices = ["off", "beat", "bar"]
group = "Live Control"

[[feature.param]]
key = "piano_hot_cues"
flag = "--piano-hot-cues"
label = "Enable low-key cue zone"
type = "bool"
default = false
group = "Live Control"

[[feature.param]]
key = "piano_cue_note_base"
flag = "--piano-cue-note-base"
label = "Cue-zone base MIDI note"
type = "int"
default = 21
min = 0
max = 120
group = "Live Control"

[[feature.param]]
key = "dashboard_port"
flag = "--dashboard-port"
label = "Browser dashboard port"
type = "int"
default = 8765
min = 0
max = 65535
group = "Live Control"

[[feature.param]]
key = "osc_port"
flag = "--osc-port"
label = "OSC control port"
type = "int"
default = 9000
min = 0
max = 65535
group = "Live Control"

[[feature.param]]
key = "osc_state_port"
flag = "--osc-state-port"
label = "OSC state output port"
type = "int"
default = 9001
min = 0
max = 65535
group = "Live Control"

[[feature.param]]
key = "capacity"
flag = "--capacity"
label = "GPU particle capacity"
type = "choice"
default = "32768"
choices = ["8192", "16384", "32768", "65536"]
group = "Performance & Advanced"

[[feature.param]]
key = "display"
flag = "--display"
label = "Projector display"
type = "int"
default = 1
min = 0
max = 8
group = "Output & Resolution"

[[feature.param]]
key = "render_width"
flag = "--render-width"
label = "Render width"
type = "int"
default = 768
min = 320
max = 1920
group = "Output & Resolution"

[[feature.param]]
key = "render_height"
flag = "--render-height"
label = "Render height"
type = "int"
default = 432
min = 180
max = 1080
group = "Output & Resolution"

[[feature.param]]
key = "projector_width"
flag = "--projector-width"
label = "Projector width"
type = "int"
default = 1920
min = 320
max = 7680
group = "Output & Resolution"

[[feature.param]]
key = "projector_height"
flag = "--projector-height"
label = "Projector height"
type = "int"
default = 1080
min = 240
max = 4320
group = "Output & Resolution"
Loading
Loading