{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://memlnaut/schemas/mode.schema.json", "title": "MEMLNaut Mode Schema", "description": "Meta-schema for one MEMLNaut mode: parameter contract, ML config, and UI hints. The schemas/modes/*.json files it validates are the canonical contract — codegen/generate.ts emits the C++ headers (nisps/modes/generated/) and TypeScript modules (manifold/src/modes/generated/) from them. Provenance notes and judgement calls live in schemas/modes/params_notes.md.", "type": "object", "required": [ "mode_id", "engine_id", "ml", "params", "voice_spaces", "ui" ], "additionalProperties": false, "properties": { "$schema": { "type": "string" }, "_note": { "type": "string", "description": "Free-text note from the schema author (e.g. about ranges that were guessed)." }, "mode_id": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "description": "snake_case identifier for the mode. Must be unique." }, "engine_id": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "description": "snake_case identifier for the audio engine the mode uses." }, "ml": { "type": "object", "required": [ "input_channels", "input_size", "hidden_layers", "output_size", "default_spread" ], "additionalProperties": false, "properties": { "input_channels": { "type": "array", "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "minItems": 1, "description": "Names of abstract input channels (e.g. joy_x, midi_velocity, audio_pitch)." }, "input_size": { "type": "integer", "minimum": 1 }, "hidden_layers": { "type": "array", "items": { "type": "integer", "minimum": 1 }, "minItems": 1 }, "output_size": { "type": "integer", "minimum": 1 }, "default_spread": { "type": "number", "minimum": 0.0, "maximum": 1.0 } } }, "params": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["name", "label", "min", "max", "default", "curve", "group"], "additionalProperties": false, "properties": { "name": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$", "description": "snake_case identifier; unique within this mode." }, "label": { "type": "string" }, "min": { "type": "number" }, "max": { "type": "number" }, "default": { "type": "number" }, "curve": { "type": "string", "enum": ["linear", "exp", "log", "square", "sqrt", "sigmoid", "cubic"], "description": "DEFAULT response curve the engine applies to this slot. Descriptive, not prescriptive: the curve is applied exactly once, inside the engine's voice space. Voice spaces that deviate declare the delta in voice_spaces[].curve_overrides. Verified against engine source by codegen/tests/curve_drift_test.ts." }, "group": { "type": "string" }, "_note": { "type": "string" } } } }, "voice_spaces": { "type": "array", "description": "Voice spaces the mode supports, in the engine's VoiceSpace enum order (index i here == VoiceSpace ordinal i). A bare string is a voice space that applies every param's default `curve`; the object form additionally declares the slots where THIS voice space deviates. Only deltas are listed — the resolved per-voice-space table is codegen output.", "items": { "oneOf": [ { "type": "string" }, { "type": "object", "required": ["name", "curve_overrides"], "additionalProperties": false, "properties": { "name": { "type": "string" }, "curve_overrides": { "type": "object", "minProperties": 1, "description": "param name -> the curve THIS voice space applies, where it differs from that param's default `curve`. Redundant entries (same as the default) are a codegen error.", "additionalProperties": { "type": "string", "enum": ["linear", "exp", "log", "square", "sqrt", "sigmoid", "cubic"] } }, "_note": { "type": "string" } } } ] } }, "ui": { "type": "object", "required": ["primary_input", "show_voice_space_selector", "show_synth_visualizer"], "additionalProperties": false, "properties": { "primary_input": { "type": "string", "enum": ["xy_pad", "joystick", "sliders", "audio_in", "midi_in", "none"] }, "show_voice_space_selector": { "type": "boolean" }, "show_synth_visualizer": { "type": "boolean" } } } } }