/** * BackendAdvanced — the FULL-depth advanced backend modal bodies (dock-spec §4). * One editor per backend. All backends share the §3.1 baseline (rendered as * OutputControlRow elsewhere); these add the backend-specific fields. * * The backend transport (backends-spec workstream E) is now LIVE: editing these * fields writes the shared MFParam store, which the BackendManager reads to send * real Web MIDI CC / OSC-over-WS. This modal is the full-depth duplicate of the * inline config in OutputsBackendConfig; both write the same store. */ import type { MFParam } from '../console/model'; import type { BackendId } from './output-state'; import { defaultMidiSpec, defaultOscSpec } from './output-state'; function num(s: string, fallback: number): number { const v = parseFloat(s); return Number.isFinite(v) ? v : fallback; } const cellInput: React.CSSProperties = { width: '100%', background: 'var(--bg-1)', border: '1px solid var(--line)', borderRadius: 'var(--r-1)', color: 'var(--fg)', fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-xs)', padding: '3px 6px', }; function Th({ children }: { children: React.ReactNode }) { return (
{params.length} CCs · live Web MIDI out (backends-spec §2.3). Editing the CC map here sends in real time once a MIDI port is selected in the Outputs panel.
| Name | CC# | Ch | State |
|---|---|---|---|
| setParam(i, { midi: { ...m, name: e.target.value } })} /> | setParam(i, { midi: { ...m, cc: Math.max(0, Math.min(127, num(e.target.value, m.cc))) }, }) } /> | setParam(i, { midi: { ...m, channel: Math.max(1, Math.min(16, num(e.target.value, m.channel))), }, }) } /> | {p.status} {p.muted ? ' · muted' : ''} |
Live OSC over the WebSocket bridge (backends-spec §2.4). Set the bridge URL + per-output paths in the Outputs panel; emits only while the bridge process is connected.
| OSC path | range min | range max |
|---|---|---|
| setParam(i, { osc: { ...o, path: e.target.value } })} /> | setParam(i, { osc: { ...o, rangeMin: num(e.target.value, o.rangeMin) } })} /> | setParam(i, { osc: { ...o, rangeMax: num(e.target.value, o.rangeMax) } })} /> |
VCV adds nothing beyond the baseline (min/max = range, fixed = freeze) plus per-channel polarity. {/* TODO(backends-spec §2.6): the VCV browser↔module bridge transport is not yet wired here. */}
The synth backend's advanced surface is the group-override matrix — see the Powerful Synth Engine drawer's full depth (dock-spec §4.4 / §5). Groups: {groups.join(' · ')}.