2026-03-21 23:57:58 +01:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" >
< meta name = "apple-mobile-web-app-capable" content = "yes" >
< meta name = "mobile-web-app-capable" content = "yes" >
< title > NISPS Immersive< / title >
2026-03-22 00:36:00 +01:00
< link rel = "preconnect" href = "https://fonts.googleapis.com" >
< link rel = "preconnect" href = "https://fonts.gstatic.com" crossorigin >
< link href = "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel = "stylesheet" >
2026-03-21 23:57:58 +01:00
< link rel = "stylesheet" href = "css/a-immersive.css" >
< / head >
< body >
<!-- Back button -->
< a href = "designs.html" class = "back-btn" title = "Back to designs" >
< svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >
< path d = "M10 2L4 8l6 6" / >
< / svg >
< / a >
<!-- Synth quick controls (play button + drawer, next to back button) -->
< div class = "synth-quick-controls hidden" id = "synth-quick-controls" >
2026-03-24 10:54:13 +01:00
< button class = "play-btn" id = "quick-play" title = "Start audio + arpeggiator" >
2026-03-21 23:57:58 +01:00
< svg width = "16" height = "16" viewBox = "0 0 16 16" fill = "currentColor" id = "quick-play-icon" > < path d = "M4 2l10 6-10 6z" / > < / svg >
< / button >
< div class = "play-drawer" id = "play-drawer" >
< label > Vol < input type = "range" id = "quick-vol" min = "0" max = "1" step = "0.01" value = "0.5" > < / label >
< label > BPM < input type = "range" id = "quick-bpm" min = "40" max = "240" step = "1" value = "120" > < span id = "quick-bpm-val" > 120< / span > < / label >
< / div >
2026-03-22 23:50:56 +01:00
< select class = "preset-select" id = "synth-preset-select" title = "Synth preset" >
< option value = "" > Manual< / option >
< optgroup label = "Beginner" >
< option value = "beginner-1" > 1.1< / option >
< option value = "beginner-2" > 1.2< / option >
< option value = "beginner-3" > 1.3< / option >
< option value = "beginner-4" > 1.4< / option >
< / optgroup >
< optgroup label = "Intermediate" >
< option value = "intermediate-1" > 2.1< / option >
< option value = "intermediate-2" > 2.2< / option >
< option value = "intermediate-3" > 2.3< / option >
< option value = "intermediate-4" > 2.4< / option >
< / optgroup >
< optgroup label = "Advanced" >
< option value = "advanced-1" > 3.1< / option >
< option value = "advanced-2" > 3.2< / option >
< option value = "advanced-3" > 3.3< / option >
< / optgroup >
< optgroup label = "Expert" >
< option value = "expert-1" > 4.1< / option >
< option value = "expert-2" > 4.2< / option >
< / optgroup >
< / select >
2026-03-21 23:57:58 +01:00
< / div >
<!-- Fullscreen flow field canvas -->
< canvas id = "vis-canvas" > < / canvas >
<!-- Synth visualization canvas -->
< canvas id = "synth-vis-canvas" > < / canvas >
2026-03-24 10:54:13 +01:00
<!-- ShapeSeq UI (hidden by default, enabled with ?shapeseq=1) -->
feat(shapeseq): integrate ShapeSeq into synth mode, replace arpeggiator
- Remove Arpeggiator import and all arp references from a-app.js
- Add ShapeSeq imports (ShapeSeqEngine, StepVisualizer, ChainBuilderUI,
getDefaultBus) and lazy initialization on first audio start
- In synth mode: show ShapeSeq container (circular viz + chain builder),
hide flow-field particles. Visual mode unchanged.
- Route joystick or hand tracking inputs to shapeSeq.setSequenceInputs()
each frame; render step viz at 60fps
- Add HTML: #shapeseq-container with #shapeseq-viz canvas and
#shapeseq-chain wrapper, sequencer transport controls (play/stop,
tempo, step count)
- Add CSS: full-screen flex layout, viz takes upper 45%, chain builder
scrollable below, hidden by default
- Quick play button wires to ShapeSeq start/stop instead of arp
Closes meml-6ry. This completes ShapeSeq Phase 1.
2026-03-24 01:17:32 +01:00
< div class = "shapeseq-container hidden" id = "shapeseq-container" >
< canvas id = "shapeseq-viz" > < / canvas >
< div class = "shapeseq-chain-wrap" id = "shapeseq-chain" > < / div >
< / div >
2026-03-21 23:57:58 +01:00
<!-- Heatmap strip (top) -->
< div class = "heatmap-strip" id = "heatmap-strip" >
< div class = "heatmap-cells" id = "heatmap-cells" > < / div >
< div class = "heatmap-tooltip" id = "heatmap-tooltip" > < / div >
< / div >
<!-- Floating joystick with integrated map -->
< div class = "joystick-container" id = "joystick-container" >
< div class = "joystick-glow" id = "joystick-glow" > < / div >
< canvas id = "joy-map" width = "160" height = "160" > < / canvas >
< div class = "noise-ring" id = "noise-ring" > < / div >
< div class = "follow-badge hidden" id = "follow-badge" > FOLLOW< / div >
2026-03-22 10:01:50 +01:00
< div id = "gamepad-status" style = "color: #ff6a00; font-size: 0.6rem; text-align: center; position: absolute; bottom: -16px; left: 0; right: 0; pointer-events: none;" > < / div >
2026-03-21 23:57:58 +01:00
< / div >
feat(playground): add MediaPipe hand tracking input with dev panel
Hand tracking via webcam as alternative to joystick input:
- Right hand tracks 14 derived features (palm XY, finger curls, spread,
roll, pitch, pinch) through a separate 14-input MLP
- Left hand gesture recognition (1 finger = thumbs up, 2 = thumbs down)
with 400ms debounce hold
- Split-zone PIP display (no camera feed, skeleton only) with dashed
divider and cross-zone dimming
- Dual IML architecture: independent imlJoy (2 inputs) and imlHand
(14 inputs) with pointer swap, preserving training data per mode
- Dev panel (?devmode=true): draggable/collapsible floating panel with
sliders for MediaPipe confidence thresholds, smoothing, gesture hold
time, world landmarks toggle, and live feature bar monitor
- Visual presets always route to joystick IML (prevents dimension mismatch)
- Race condition guard on input mode switching
2026-03-23 22:28:58 +01:00
<!-- Hand tracking PIP (replaces joystick position when active) -->
< div class = "hand-pip hidden" id = "hand-pip" >
< video id = "hand-video" playsinline autoplay muted > < / video >
< canvas id = "hand-overlay" > < / canvas >
< div class = "hand-status" id = "hand-status" > Loading...< / div >
< div class = "gesture-indicator" id = "gesture-indicator" >
< svg class = "gesture-ring" viewBox = "0 0 36 36" >
< circle class = "gesture-ring-bg" cx = "18" cy = "18" r = "16" / >
< circle class = "gesture-ring-progress" cx = "18" cy = "18" r = "16" / >
< / svg >
< span class = "gesture-label" id = "gesture-label" > < / span >
< / div >
< / div >
2026-03-21 23:57:58 +01:00
<!-- RL floating buttons -->
< div class = "rl-buttons" id = "rl-buttons" >
2026-03-22 00:36:00 +01:00
< button class = "rl-btn rl-down" id = "btn-thumbsdown" title = "Explore more" > < span class = "rl-icon" > − < / span > < span class = "key-num" > 1< / span > < / button >
< button class = "rl-btn rl-up" id = "btn-thumbsup" title = "Keep this" > < span class = "rl-icon" > +< / span > < span class = "key-num" > 2< / span > < / button >
2026-03-21 23:57:58 +01:00
< / div >
<!-- Bottom sheet -->
< div class = "bottom-sheet collapsed" id = "bottom-sheet" >
<!-- Floating mode bar (sticky inside sheet) -->
< div class = "floating-bar" id = "floating-bar" >
feat(playground): add MediaPipe hand tracking input with dev panel
Hand tracking via webcam as alternative to joystick input:
- Right hand tracks 14 derived features (palm XY, finger curls, spread,
roll, pitch, pinch) through a separate 14-input MLP
- Left hand gesture recognition (1 finger = thumbs up, 2 = thumbs down)
with 400ms debounce hold
- Split-zone PIP display (no camera feed, skeleton only) with dashed
divider and cross-zone dimming
- Dual IML architecture: independent imlJoy (2 inputs) and imlHand
(14 inputs) with pointer swap, preserving training data per mode
- Dev panel (?devmode=true): draggable/collapsible floating panel with
sliders for MediaPipe confidence thresholds, smoothing, gesture hold
time, world landmarks toggle, and live feature bar monitor
- Visual presets always route to joystick IML (prevents dimension mismatch)
- Race condition guard on input mode switching
2026-03-23 22:28:58 +01:00
< div class = "pill-toggle pill-toggle-sm" id = "input-toggle" >
< button class = "pill-opt active" data-input = "joystick" > Joystick< / button >
< button class = "pill-opt" data-input = "hands" > Hands< / button >
< / div >
2026-03-22 10:07:38 +01:00
< div class = "pill-toggle pill-toggle-sm" id = "output-toggle-float" >
< button class = "pill-opt active" data-mode = "visual" > Visual< / button >
< button class = "pill-opt" data-mode = "synth" > Synth< / button >
< / div >
2026-03-22 10:01:50 +01:00
< button class = "float-btn accent" id = "btn-train-bar" title = "Train on examples" > Train< / button >
2026-03-21 23:57:58 +01:00
< button class = "float-btn" id = "btn-randomize-bar" title = "Randomize weights" > Randomize< / button >
2026-03-22 10:01:50 +01:00
< button class = "float-btn" id = "btn-clear-examples-bar" title = "Clear examples" > Clear Ex< / button >
2026-03-21 23:57:58 +01:00
< button class = "follow-pill" id = "follow-pill" title = "Toggle follow mode" > Follow< / button >
2026-03-25 10:55:58 +01:00
< button class = "osc-pill" id = "osc-pill" title = "Connect OSC output" > OSC< / button >
2026-03-21 23:57:58 +01:00
< button class = "chevron-btn" id = "chevron-btn" title = "Expand panel" > ▲ < / button >
< / div >
<!-- Status line -->
< div class = "sheet-status" id = "sheet-status" >
< span id = "status-text" > 0 examples · untrained< / span >
< / div >
<!-- Sheet content -->
< div class = "sheet-content" id = "sheet-content" >
<!-- Examples mode actions -->
2026-03-22 10:01:50 +01:00
< div class = "action-row" id = "examples-actions" >
2026-03-21 23:57:58 +01:00
< button class = "action-btn" id = "btn-add-example" > Add Example< / button >
< button class = "action-btn accent" id = "btn-train" > Train< / button >
2026-03-22 10:01:50 +01:00
< button class = "action-btn dim" id = "btn-clear-examples" > Clear Examples< / button >
< button class = "action-btn dim" id = "btn-clear" > Clear All< / button >
2026-03-21 23:57:58 +01:00
< button class = "action-btn dim" id = "btn-randomize" > Randomize< / button >
< / div >
<!-- Preset palette -->
2026-03-22 10:01:50 +01:00
< div class = "preset-row" id = "preset-row" >
2026-03-21 23:57:58 +01:00
< span class = "preset-label" > Presets< / span >
< button class = "preset-chip" data-preset = "calm-to-chaotic" > Calm/Chaos< / button >
< button class = "preset-chip" data-preset = "rainbow-sweep" > Rainbow< / button >
< button class = "preset-chip" data-preset = "vortex" > Vortex< / button >
< button class = "preset-chip" data-preset = "spiral" > Spiral< / button >
< button class = "preset-chip" data-preset = "embers" > Embers< / button >
< / div >
<!-- Synth controls -->
< div class = "synth-panel hidden" id = "synth-panel" >
< div class = "synth-row" >
< button class = "action-btn accent" id = "synth-start" > Start Audio< / button >
< span class = "synth-status" id = "synth-status" > Stopped< / span >
< / div >
< div class = "synth-row" >
< label > Volume< / label >
< input type = "range" id = "synth-volume" min = "0" max = "1" step = "0.01" value = "0.5" >
< / div >
< div class = "synth-row" >
2026-03-24 10:54:13 +01:00
< label > Arpeggiator< / label >
< button class = "action-btn" id = "arp-toggle" > Play< / button >
< / div >
< div class = "synth-row" >
< label > Progression< / label >
< select id = "arp-progression" >
< option value = "I-vi-IV-V" > I-vi-IV-V< / option >
< option value = "I-IV-vi-V" > I-IV-vi-V< / option >
< option value = "i-VI-III-VII" > i-VI-III-VII< / option >
< option value = "I-V-vi-IV" > I-V-vi-IV< / option >
< / select >
2026-03-21 23:57:58 +01:00
< / div >
< div class = "synth-row" >
< label > Tempo < span id = "tempo-val" > 120< / span > < / label >
2026-03-24 10:54:13 +01:00
< input type = "range" id = "arp-tempo" min = "40" max = "240" step = "1" value = "120" >
< / div >
< div class = "synth-row" >
< label > Octaves < span id = "octaves-val" > 2< / span > < / label >
< input type = "range" id = "arp-octaves" min = "1" max = "5" step = "1" value = "2" >
2026-03-21 23:57:58 +01:00
< / div >
< div class = "synth-row" >
2026-03-24 10:54:13 +01:00
< label > Oct Offset < span id = "offset-val" > 0< / span > < / label >
< input type = "range" id = "arp-offset" min = "-2" max = "3" step = "1" value = "0" >
2026-03-21 23:57:58 +01:00
< / div >
2026-03-22 10:01:50 +01:00
< div class = "synth-row" id = "midi-row" style = "display:none" >
< label > MIDI Input< / label >
< button class = "action-btn" id = "midi-toggle" > Enable< / button >
< select id = "midi-select" style = "flex:1;min-width:0" > < / select >
< / div >
< div class = "synth-row" id = "midi-status-row" style = "display:none" >
< span class = "synth-status" id = "midi-status" > < / span >
< / div >
2026-03-25 11:01:12 +01:00
< div class = "synth-row osc-row-panel" id = "osc-row" >
2026-03-25 10:55:58 +01:00
< label > OSC Output< / label >
< button class = "action-btn" id = "osc-toggle" > Connect< / button >
< span class = "synth-status" id = "osc-status" > Off< / span >
< / div >
2026-03-21 23:57:58 +01:00
< / div >
<!-- Loss plot -->
< div class = "loss-section" >
< label > Loss History< / label >
< canvas id = "loss-canvas" width = "280" height = "80" > < / canvas >
< / div >
<!-- Advanced: raw param sliders -->
< details class = "advanced-section" >
< summary > Advanced: Raw Parameters< / summary >
< div class = "raw-params" id = "raw-params" > < / div >
< / details >
< / div >
< / div >
2026-03-22 21:41:49 +01:00
<!-- Help button -->
< button class = "help-btn" id = "help-btn" title = "Help" > ?< / button >
<!-- Help modal -->
< div class = "help-overlay hidden" id = "help-overlay" >
< div class = "help-modal" id = "help-modal" >
< button class = "help-close" id = "help-close" > × < / button >
< h2 > Welcome to NISPS< / h2 >
< p class = "help-subtitle" > Neural Interactive Shaping of Parameter Spaces< / p >
< div class = "help-section" >
< h3 > What is this?< / h3 >
< p > NISPS lets you < strong > teach a neural network< / strong > how to map a 2D joystick position to a rich set of visual or audio parameters. Move the joystick, shape the outputs you want, and the network learns your preferences in real time.< / p >
< / div >
< div class = "help-section" >
< h3 > How it works< / h3 >
< p > A small neural network takes your joystick X/Y position as input and produces dozens of output parameters. You teach it by either:< / p >
< ul >
< li > < strong > Examples< / strong > — set the parameter sliders to what you want at a given joystick position, add the example, then hit Train. Do this a few times from different positions and the network interpolates between them.< / li >
< li > < strong > Feedback (RL)< / strong > — move the joystick around. If you like what you see/hear, press < strong > +< / strong > (keep this). If you don't, press < strong > − < / strong > (explore more). The network gradually learns what you prefer.< / li >
< / ul >
< / div >
< div class = "help-section" >
< h3 > What to expect< / h3 >
< ul >
< li > < strong > Moving the joystick< / strong > changes all outputs in real time through the network< / li >
< li > < strong > Randomize< / strong > shuffles the network weights — instant new mapping< / li >
< li > < strong > Train< / strong > fits the network to your saved examples< / li >
< li > < strong > + / − feedback< / strong > nudges the network: + reinforces the current mapping, − adds exploration noise< / li >
< li > Switch between < strong > Visual< / strong > (particle flow field) and < strong > Synth< / strong > (C15 synthesizer) output modes< / li >
< li > The < strong > heatmap bar< / strong > at the top shows all output parameters at a glance< / li >
< / ul >
< / div >
< div class = "help-section" >
< h3 > Controls< / h3 >
< table class = "help-keys" >
< tr > < th colspan = "2" > Touch / Mouse< / th > < / tr >
< tr > < td > Drag joystick< / td > < td > Move through parameter space< / td > < / tr >
< tr > < td > + / − buttons< / td > < td > Positive / negative feedback< / td > < / tr >
< tr > < td > Bottom bar< / td > < td > Train, Randomize, Clear, Follow mode< / td > < / tr >
< tr > < th colspan = "2" > Keyboard< / th > < / tr >
< tr > < td > < kbd > 1< / kbd > < / td > < td > Negative feedback (− )< / td > < / tr >
< tr > < td > < kbd > 2< / kbd > < / td > < td > Positive feedback (+)< / td > < / tr >
< tr > < th colspan = "2" > Gamepad (Steam Deck, Xbox, etc.)< / th > < / tr >
< tr > < td > Left stick< / td > < td > Joystick control< / td > < / tr >
< tr > < td > LB (left bumper)< / td > < td > Negative feedback< / td > < / tr >
< tr > < td > RB (right bumper)< / td > < td > Positive feedback< / td > < / tr >
< tr > < td > A< / td > < td > Train< / td > < / tr >
< tr > < td > X< / td > < td > Randomize< / td > < / tr >
< tr > < td > B< / td > < td > Clear examples< / td > < / tr >
< / table >
< / div >
feat(playground): add MediaPipe hand tracking input with dev panel
Hand tracking via webcam as alternative to joystick input:
- Right hand tracks 14 derived features (palm XY, finger curls, spread,
roll, pitch, pinch) through a separate 14-input MLP
- Left hand gesture recognition (1 finger = thumbs up, 2 = thumbs down)
with 400ms debounce hold
- Split-zone PIP display (no camera feed, skeleton only) with dashed
divider and cross-zone dimming
- Dual IML architecture: independent imlJoy (2 inputs) and imlHand
(14 inputs) with pointer swap, preserving training data per mode
- Dev panel (?devmode=true): draggable/collapsible floating panel with
sliders for MediaPipe confidence thresholds, smoothing, gesture hold
time, world landmarks toggle, and live feature bar monitor
- Visual presets always route to joystick IML (prevents dimension mismatch)
- Race condition guard on input mode switching
2026-03-23 22:28:58 +01:00
< div class = "help-section" >
< h3 > Hand Tracking< / h3 >
< p > Toggle to < strong > Hands< / strong > mode in the bottom bar to use your webcam for input.< / p >
< ul >
< li > < strong > Right hand< / strong > controls parameters — palm position, finger curls, spread, rotation, and pinch map to 14 input dimensions< / li >
< li > < strong > Left hand< / strong > gives feedback via gestures:< / li >
< ul >
< li > < strong > 1 finger< / strong > (index) held 0.4s → positive feedback (+)< / li >
< li > < strong > 2 fingers< / strong > (index + middle) held 0.4s → negative feedback (− )< / li >
< / ul >
< li > If only one hand is visible, it's treated as the tracking hand — use keyboard/buttons for feedback< / li >
< li > Camera permission is requested only when you switch to Hands mode< / li >
< / ul >
< / div >
2026-03-22 21:41:49 +01:00
< div class = "help-section" >
< h3 > Tips< / h3 >
< ul >
< li > Start with < strong > Randomize< / strong > a few times to hear/see different mappings, then use feedback to refine< / li >
< li > Use < strong > Follow< / strong > mode to let the joystick wander automatically while you give feedback< / li >
2026-03-22 21:47:55 +01:00
< li > In Synth mode, press the < strong > play button< / strong > (top left, pulses orange when audio is off) to start audio, then explore< / li >
2026-03-22 21:41:49 +01:00
< li > Tap a heatmap cell to see which parameter it controls< / li >
< / ul >
< / div >
2026-03-22 21:47:55 +01:00
< div class = "help-section" >
< h3 > Synth Controls< / h3 >
< ul >
2026-03-22 23:50:56 +01:00
< li > < strong > Presets< / strong > — use the dropdown (top left, next to play) to choose a parameter preset. Lower tiers (1.x) expose fewer parameters for simpler exploration; higher tiers (3.x, 4.x) unlock cross-modulation, feedback, and the full engine. You can tweak any preset afterwards using the controls below.< / li >
2026-03-22 21:47:55 +01:00
< li > < strong > Hover any bar< / strong > in the synth visualizer to see parameter name, current value, range, and curve< / li >
< li > < strong > Hover a group name< / strong > (e.g. "Env A", "Osc B") at the top to open its control drawer:< / li >
< ul >
< li > < strong > Group curve< / strong > — drag the top graph vertically to shape the response curve for the whole group (adjusts all param curves relatively)< / li >
< li > < strong > Per-param curve< / strong > — drag each small graph to shape that parameter individually (down = exponential, up = logarithmic)< / li >
< li > < strong > Min/Max range< / strong > — dual-thumb slider constrains the parameter's output range< / li >
< li > < strong > Mute (M)< / strong > — removes the parameter from NISPS control; its bar disappears and you get a manual value slider instead< / li >
< / ul >
< li > < strong > MIDI input< / strong > — connect a MIDI controller and it will be detected automatically; MIDI notes trigger the synth directly< / li >
2026-03-24 10:54:13 +01:00
< li > < strong > Arpeggiator< / strong > — expand the bottom bar to access the built-in arpeggiator with tempo, octave range, offset, and chord progression controls; press Pause to stop it< / li >
2026-03-22 21:47:55 +01:00
< / ul >
< / div >
2026-03-25 10:55:58 +01:00
< div class = "help-section" >
< h3 > OSC Output< / h3 >
< p > Send NISPS parameters to any OSC-capable software (SuperCollider, Max/MSP, Pure Data, TouchDesigner, Ableton, etc.) via a small bridge script that runs on your computer.< / p >
< div class = "help-osc-steps" >
< p > < strong > 1. Download the bridge< / strong > < / p >
< div class = "help-download-row" >
< button class = "help-download-btn" id = "osc-download-bin" > Download for < span id = "osc-platform-name" > your OS< / span > < / button >
< button class = "help-download-btn help-download-alt" id = "osc-download-src" > Source (.ts)< / button >
< / div >
< p class = "help-dim" > Binary is standalone, no runtime needed. Source requires < a href = "https://deno.land" target = "_blank" rel = "noopener" > Deno< / a > or < a href = "https://nodejs.org" target = "_blank" rel = "noopener" > Node.js< / a > .< / p >
< p > < strong > 2. Run< / strong > < / p >
< pre class = "help-code" id = "osc-run-instructions" > ./nisps-osc-bridge< / pre >
< p > < strong > 3. Connect< / strong > < / p >
2026-03-25 11:01:12 +01:00
< p > Click the < strong > OSC< / strong > button in the bottom bar (visible in all modes). The dot turns green when connected. You can also find a Connect button in the synth panel when expanded.< / p >
2026-03-25 10:55:58 +01:00
< / div >
< p style = "margin-top:10px" > < strong > Configuration< / strong > < / p >
< table class = "help-keys" >
< tr > < td > < kbd > --osc-port 9000< / kbd > < / td > < td > Target port (default: 57120 / SuperCollider)< / td > < / tr >
< tr > < td > < kbd > --osc-host 192.168.1.5< / kbd > < / td > < td > Target IP (default: 127.0.0.1)< / td > < / tr >
< tr > < td > < kbd > --osc-prefix /my< / kbd > < / td > < td > Address prefix (default: /nisps)< / td > < / tr >
< tr > < td > < kbd > --ws-port 8000< / kbd > < / td > < td > WebSocket listen port (default: 8765)< / td > < / tr >
< tr > < td > < kbd > --bundle< / kbd > < / td > < td > Send OSC bundles instead of individual messages< / td > < / tr >
< / table >
< p style = "margin-top:10px" > < strong > OSC addresses< / strong > < / p >
< p > Each parameter is sent as < code > /nisps/< Param_Name> < float 0– 1> < / code > . All 126 synth parameters are available. Values reflect your current preset, curves, and tame settings. Examples:< / p >
< pre class = "help-code" > /nisps/Env_A_Att 0.35
/nisps/SVF_Flt_Cut 0.72
/nisps/Reverb_Mix 0.15< / pre >
< details class = "help-details" >
< summary > SuperCollider example< / summary >
< pre class = "help-code" > // Listen for all NISPS params
OSCdef(\nisps, { |msg, time|
msg.postln;
}, '/nisps/*');
// Map a specific param to a synth
OSCdef(\cutoff, { |msg|
~synth.set(\freq, msg[1].linexp(0, 1, 200, 8000));
}, '/nisps/SVF_Flt_Cut');< / pre >
< / details >
< details class = "help-details" >
< summary > Pure Data example< / summary >
< pre class = "help-code" > [netreceive -u -b 57120]
|
[oscparse]
|
[route /nisps]
|
[route /Env_A_Att /SVF_Flt_Cut ...]< / pre >
< / details >
< details class = "help-details" >
< summary > Max/MSP example< / summary >
< pre class = "help-code" > [udpreceive 57120]
|
[OSC-route /nisps/Env_A_Att]
|
[scale 0. 1. 200. 8000.]< / pre >
< / details >
< / div >
2026-03-22 21:41:49 +01:00
< button class = "help-got-it" id = "help-got-it" > Got it< / button >
< / div >
< / div >
2026-03-21 23:57:58 +01:00
< script type = "module" src = "js/a-app.js" > < / script >
< / body >
< / html >