2026-02-11 13:17:17 +01:00
|
|
|
// Parameter bar display
|
2026-02-11 16:44:33 +01:00
|
|
|
// Shows output parameters as horizontal bars, draggable in examples mode
|
2026-02-11 13:17:17 +01:00
|
|
|
|
feat(playground): add C15 synth mode with NISPS-controlled parameters and arpeggiator
Adds a secondary Synth mode (toggled via collapsible left side panel)
where the NISPS ML engine's 20 outputs control curated C15 synthesizer
parameters (oscillator PM, shapers, filters, reverb, echo, flanger,
output mixer) through a WASM AudioWorklet bridge.
Includes a chord progression arpeggiator with controls for tempo (BPM),
octave range, octave offset, and 4 selectable progressions. The C15
engine runs in an AudioWorklet with lock-free SharedArrayBuffer ring
buffer communication.
New files: c15/ (WASM assets), js/synth/ (bridge, arpeggiator, param map),
serve-coop.py (COOP/COEP headers for SharedArrayBuffer support).
2026-03-21 21:26:37 +01:00
|
|
|
const DEFAULT_PARAM_NAMES = ['Flow', 'Scale', 'Speed', 'Hue', 'Spread', 'Size', 'Trail', 'Turb', 'Attract', 'Radius', 'DispRate', 'DispAmt', 'Lifetime', 'Respawn', 'Advection', 'Inertia', 'Drag', 'Repulse', 'RepCnt', 'RepRate'];
|
|
|
|
|
const DEFAULT_PARAM_COLORS = ['#00ff88', '#00ccff', '#ff6600', '#ff00cc', '#ffcc00', '#88ff00', '#0088ff', '#ff3366', '#9bff5f', '#59d3ff', '#ff8f3f', '#a0b7ff', '#f4ff7a', '#ffa8db', '#7dffc8', '#ffd166', '#8ad4ff', '#ff5f5f', '#ffc15f', '#ff8a3d'];
|
2026-02-11 13:17:17 +01:00
|
|
|
|
|
|
|
|
export class ParamDisplay {
|
2026-02-11 16:50:06 +01:00
|
|
|
constructor(container, numParams = 20) {
|
2026-02-11 13:17:17 +01:00
|
|
|
this.container = container;
|
|
|
|
|
this.numParams = numParams;
|
|
|
|
|
this.values = new Array(numParams).fill(0.5);
|
|
|
|
|
this.draggable = false;
|
|
|
|
|
this.onChange = null;
|
|
|
|
|
this.activeBar = -1;
|
feat(playground): add C15 synth mode with NISPS-controlled parameters and arpeggiator
Adds a secondary Synth mode (toggled via collapsible left side panel)
where the NISPS ML engine's 20 outputs control curated C15 synthesizer
parameters (oscillator PM, shapers, filters, reverb, echo, flanger,
output mixer) through a WASM AudioWorklet bridge.
Includes a chord progression arpeggiator with controls for tempo (BPM),
octave range, octave offset, and 4 selectable progressions. The C15
engine runs in an AudioWorklet with lock-free SharedArrayBuffer ring
buffer communication.
New files: c15/ (WASM assets), js/synth/ (bridge, arpeggiator, param map),
serve-coop.py (COOP/COEP headers for SharedArrayBuffer support).
2026-03-21 21:26:37 +01:00
|
|
|
this.paramNames = [...DEFAULT_PARAM_NAMES];
|
|
|
|
|
this.paramColors = [...DEFAULT_PARAM_COLORS];
|
2026-02-11 13:17:17 +01:00
|
|
|
this.build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
build() {
|
|
|
|
|
this.container.innerHTML = '';
|
|
|
|
|
this.bars = [];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.numParams; i++) {
|
|
|
|
|
const row = document.createElement('div');
|
|
|
|
|
row.className = 'param-row';
|
|
|
|
|
|
|
|
|
|
const label = document.createElement('span');
|
|
|
|
|
label.className = 'param-label';
|
feat(playground): add C15 synth mode with NISPS-controlled parameters and arpeggiator
Adds a secondary Synth mode (toggled via collapsible left side panel)
where the NISPS ML engine's 20 outputs control curated C15 synthesizer
parameters (oscillator PM, shapers, filters, reverb, echo, flanger,
output mixer) through a WASM AudioWorklet bridge.
Includes a chord progression arpeggiator with controls for tempo (BPM),
octave range, octave offset, and 4 selectable progressions. The C15
engine runs in an AudioWorklet with lock-free SharedArrayBuffer ring
buffer communication.
New files: c15/ (WASM assets), js/synth/ (bridge, arpeggiator, param map),
serve-coop.py (COOP/COEP headers for SharedArrayBuffer support).
2026-03-21 21:26:37 +01:00
|
|
|
label.textContent = this.paramNames[i] || `p${i}`;
|
2026-02-11 13:17:17 +01:00
|
|
|
|
|
|
|
|
const track = document.createElement('div');
|
|
|
|
|
track.className = 'param-track';
|
|
|
|
|
track.dataset.index = i;
|
|
|
|
|
|
|
|
|
|
const fill = document.createElement('div');
|
|
|
|
|
fill.className = 'param-fill';
|
feat(playground): add C15 synth mode with NISPS-controlled parameters and arpeggiator
Adds a secondary Synth mode (toggled via collapsible left side panel)
where the NISPS ML engine's 20 outputs control curated C15 synthesizer
parameters (oscillator PM, shapers, filters, reverb, echo, flanger,
output mixer) through a WASM AudioWorklet bridge.
Includes a chord progression arpeggiator with controls for tempo (BPM),
octave range, octave offset, and 4 selectable progressions. The C15
engine runs in an AudioWorklet with lock-free SharedArrayBuffer ring
buffer communication.
New files: c15/ (WASM assets), js/synth/ (bridge, arpeggiator, param map),
serve-coop.py (COOP/COEP headers for SharedArrayBuffer support).
2026-03-21 21:26:37 +01:00
|
|
|
fill.style.background = this.paramColors[i] || '#888';
|
2026-02-11 13:17:17 +01:00
|
|
|
fill.style.width = '50%';
|
|
|
|
|
|
|
|
|
|
const val = document.createElement('span');
|
|
|
|
|
val.className = 'param-value';
|
|
|
|
|
val.textContent = '0.50';
|
|
|
|
|
|
|
|
|
|
track.appendChild(fill);
|
|
|
|
|
row.appendChild(label);
|
|
|
|
|
row.appendChild(track);
|
|
|
|
|
row.appendChild(val);
|
|
|
|
|
this.container.appendChild(row);
|
|
|
|
|
|
|
|
|
|
this.bars.push({ fill, val, track });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Touch/mouse drag events on the container
|
|
|
|
|
const onStart = (e) => {
|
|
|
|
|
if (!this.draggable) return;
|
|
|
|
|
const target = e.target.closest('.param-track');
|
|
|
|
|
if (!target) return;
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
this.activeBar = parseInt(target.dataset.index);
|
|
|
|
|
this._updateFromEvent(e);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onMove = (e) => {
|
|
|
|
|
if (this.activeBar < 0 || !this.draggable) return;
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
this._updateFromEvent(e);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onEnd = () => {
|
|
|
|
|
this.activeBar = -1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.container.addEventListener('mousedown', onStart);
|
|
|
|
|
window.addEventListener('mousemove', onMove);
|
|
|
|
|
window.addEventListener('mouseup', onEnd);
|
|
|
|
|
this.container.addEventListener('touchstart', onStart, { passive: false });
|
|
|
|
|
this.container.addEventListener('touchmove', onMove, { passive: false });
|
|
|
|
|
this.container.addEventListener('touchend', onEnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_updateFromEvent(e) {
|
|
|
|
|
const i = this.activeBar;
|
|
|
|
|
if (i < 0) return;
|
|
|
|
|
const track = this.bars[i].track;
|
|
|
|
|
const rect = track.getBoundingClientRect();
|
|
|
|
|
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
|
|
|
|
|
const value = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
|
|
|
|
|
this.values[i] = value;
|
|
|
|
|
this._renderBar(i);
|
|
|
|
|
if (this.onChange) this.onChange(i, value, this.values);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update(values) {
|
|
|
|
|
for (let i = 0; i < this.numParams && i < values.length; i++) {
|
|
|
|
|
this.values[i] = values[i];
|
|
|
|
|
this._renderBar(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_renderBar(i) {
|
|
|
|
|
const v = this.values[i];
|
|
|
|
|
this.bars[i].fill.style.width = (v * 100) + '%';
|
|
|
|
|
this.bars[i].val.textContent = v.toFixed(2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setDraggable(draggable) {
|
|
|
|
|
this.draggable = draggable;
|
|
|
|
|
this.container.classList.toggle('draggable', draggable);
|
|
|
|
|
}
|
feat(playground): add C15 synth mode with NISPS-controlled parameters and arpeggiator
Adds a secondary Synth mode (toggled via collapsible left side panel)
where the NISPS ML engine's 20 outputs control curated C15 synthesizer
parameters (oscillator PM, shapers, filters, reverb, echo, flanger,
output mixer) through a WASM AudioWorklet bridge.
Includes a chord progression arpeggiator with controls for tempo (BPM),
octave range, octave offset, and 4 selectable progressions. The C15
engine runs in an AudioWorklet with lock-free SharedArrayBuffer ring
buffer communication.
New files: c15/ (WASM assets), js/synth/ (bridge, arpeggiator, param map),
serve-coop.py (COOP/COEP headers for SharedArrayBuffer support).
2026-03-21 21:26:37 +01:00
|
|
|
|
|
|
|
|
setNamesAndColors(names, colors) {
|
|
|
|
|
this.paramNames = names || DEFAULT_PARAM_NAMES;
|
|
|
|
|
this.paramColors = colors || DEFAULT_PARAM_COLORS;
|
|
|
|
|
// Update existing bars in-place
|
|
|
|
|
for (let i = 0; i < this.numParams; i++) {
|
|
|
|
|
if (!this.bars[i]) continue;
|
|
|
|
|
const row = this.bars[i].fill.closest('.param-row');
|
|
|
|
|
const label = row?.querySelector('.param-label');
|
|
|
|
|
if (label) label.textContent = this.paramNames[i] || `p${i}`;
|
|
|
|
|
this.bars[i].fill.style.background = this.paramColors[i] || '#888';
|
|
|
|
|
}
|
|
|
|
|
}
|
feat(playground): expand C15 param map from 20 to 126 synth parameters
Control all sonically meaningful C15 parameters through NISPS ML outputs.
Excludes hardware routing, macros, scale/tuning, key tracking, velocity,
envelope mod depths, discrete switches, and dangerous volume/pitch params.
- Expand param-map.js with 126 curated params grouped by synthesis section
- Widen MLP architecture from [3,10,10,14,20] to [3,32,48,64,126]
- Add ParamDisplay.rebuild() for mode-dependent bar count (20 visual, 126 synth)
- Add scrollable compact layout for synth mode param bars
- Pad visual presets and old saves to 126 outputs for backward compatibility
2026-03-21 21:58:48 +01:00
|
|
|
|
|
|
|
|
rebuild(numParams, names, colors) {
|
|
|
|
|
this.numParams = numParams;
|
|
|
|
|
this.values = new Array(numParams).fill(0.5);
|
|
|
|
|
this.paramNames = names || DEFAULT_PARAM_NAMES;
|
|
|
|
|
this.paramColors = colors || DEFAULT_PARAM_COLORS;
|
|
|
|
|
this.activeBar = -1;
|
|
|
|
|
this.build();
|
|
|
|
|
}
|
2026-02-11 13:17:17 +01:00
|
|
|
}
|