112 lines
3.7 KiB
JSON
112 lines
3.7 KiB
JSON
|
|
{
|
||
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
|
|
"$id": "https://memlnaut/schemas/mode.schema.json",
|
||
|
|
"title": "MEMLNaut Mode Schema",
|
||
|
|
"description": "Describes the parameter contract, ML config, and UI hints for one MEMLNaut mode. Authoritative source: firmware C++ code under modes/ and voicespaces/. Codegen consumes this to emit C++ headers and TypeScript types.",
|
||
|
|
"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",
|
||
|
|
"default_learning_rate",
|
||
|
|
"default_max_iterations"
|
||
|
|
],
|
||
|
|
"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 },
|
||
|
|
"default_learning_rate": { "type": "number", "exclusiveMinimum": 0.0 },
|
||
|
|
"default_max_iterations": { "type": "integer", "minimum": 1 }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"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"]
|
||
|
|
},
|
||
|
|
"group": { "type": "string" },
|
||
|
|
"_note": { "type": "string" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"voice_spaces": {
|
||
|
|
"type": "array",
|
||
|
|
"items": { "type": "string" },
|
||
|
|
"description": "Names of C++ voice space lambdas the mode supports. May be empty for engines with no voice spaces (e.g. sequencers)."
|
||
|
|
},
|
||
|
|
"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" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|