{
"id": "at.atmosynth.patch",
"defs": {
"main": {
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"descriptionVersion",
"name",
"description",
"moduleInstances",
"createdAt"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"tags": {
"type": "array",
"items": {
"type": "string",
"maxLength": 128
},
"description": "Freely created tags, lower-cased on write so one hashtag matches one set of patches."
},
"types": {
"type": "array",
"items": {
"type": "string",
"knownValues": [
"Lead",
"Pad",
"Bass",
"Plucked",
"Percussion",
"Keys",
"Brass",
"Strings",
"Vocal",
"SFX"
]
},
"description": "Zero or more of the ten fixed types. A patch may carry several."
},
"output": {
"ref": "#outputRef",
"type": "ref",
"description": "Which instance reaches the audio output."
},
"createdAt": {
"type": "string",
"format": "datetime"
},
"forkedFrom": {
"ref": "#lineage",
"type": "ref"
},
"connections": {
"type": "array",
"items": {
"ref": "#connection",
"type": "ref"
}
},
"description": {
"type": "string",
"maxLength": 3000
},
"midiRouting": {
"type": "array",
"items": {
"ref": "#midiRoute",
"type": "ref"
},
"description": "Which module instances receive MIDI input."
},
"moduleInstances": {
"type": "array",
"items": {
"ref": "#moduleInstance",
"type": "ref"
}
},
"descriptionVersion": {
"type": "integer",
"minimum": 1,
"description": "Version of the patch description this record follows."
}
}
},
"description": "A patch, held in its creator's own repository."
},
"lineage": {
"type": "object",
"required": [
"uri",
"creatorDid"
],
"properties": {
"uri": {
"type": "string",
"format": "at-uri"
},
"patchId": {
"type": "string",
"maxLength": 128
},
"creatorDid": {
"type": "string",
"format": "did"
}
},
"description": "The patch this one was forked from, and its creator. Preserved even when the source is later deleted."
},
"inputRef": {
"type": "object",
"required": [
"instanceId",
"audioInput"
],
"properties": {
"audioInput": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"instanceId": {
"type": "string",
"maxLength": 64,
"minLength": 1
}
}
},
"position": {
"type": "object",
"required": [
"x",
"y"
],
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
}
}
},
"midiRoute": {
"type": "object",
"required": [
"instanceId",
"midiInput"
],
"properties": {
"midiInput": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"instanceId": {
"type": "string",
"maxLength": 64,
"minLength": 1
}
}
},
"moduleRef": {
"type": "object",
"required": [
"moduleId",
"versionKey",
"authorDid"
],
"properties": {
"moduleId": {
"type": "string",
"maxLength": 128,
"minLength": 1
},
"authorDid": {
"type": "string",
"format": "did"
},
"versionKey": {
"type": "string",
"maxLength": 128,
"minLength": 1
}
},
"description": "A pin to one exact published version of a module. Resolving it fetches that record, whoever authored it."
},
"outputRef": {
"type": "object",
"required": [
"instanceId",
"audioOutput"
],
"properties": {
"instanceId": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"audioOutput": {
"type": "string",
"maxLength": 64,
"minLength": 1
}
}
},
"connection": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"ref": "#inputRef",
"type": "ref"
},
"from": {
"ref": "#outputRef",
"type": "ref"
}
},
"description": "An audio connection between two module instances, naming the declared ports at each end."
},
"midiControl": {
"type": "object",
"required": [
"parameter",
"controller"
],
"properties": {
"parameter": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The id of the exposed parameter this control moves. One parameter is moved by at most one controller; one controller may move several parameters."
},
"controller": {
"type": "integer",
"maximum": 127,
"minimum": 0,
"description": "The control change number. Five are spoken for by MIDI itself and cannot be bound: 64, the sustain pedal, and 6, 38, 100 and 101, which carry registered-parameter traffic."
}
},
"description": "One MIDI control change bound to one of the module's exposed parameters. The controller's 0 to 127 sweeps the parameter across the range the module declares, or, where the module declares a closed value set instead, across those values in order. A control is read from every input on every channel, like every other MIDI message here: there is nothing to configure."
},
"moduleInstance": {
"type": "object",
"required": [
"instanceId",
"module"
],
"properties": {
"module": {
"ref": "#moduleRef",
"type": "ref"
},
"position": {
"ref": "#position",
"type": "ref",
"description": "Where the creator placed this instance in the patch's arrangement, so the arrangement travels with the patch and a fork inherits it. Optional permanently, and the only field in either description that exists for presentation."
},
"instanceId": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"voiceScope": {
"type": "string",
"description": "Whether this instance is built once for each sounding note or once for the whole patch. Optional permanently: an unset scope is worked out when the patch is played, and is never written on a creator's behalf.",
"knownValues": [
"perNote",
"perPatch"
]
},
"midiControls": {
"type": "array",
"items": {
"ref": "#midiControl",
"type": "ref"
},
"description": "Which MIDI control changes move this instance's parameters while it is played. A binding lives here, in the patch, because which knob moves what is a decision about this use of the module and not about the module."
},
"parameterValues": {
"type": "array",
"items": {
"ref": "#parameterValue",
"type": "ref"
}
},
"sampleSlotFills": {
"type": "array",
"items": {
"ref": "#sampleSlotFill",
"type": "ref"
},
"description": "Samples this instance supplies for the module's declared slots. A fill lives here, in the patch, so writing one never touches the module."
}
},
"description": "One use of one module version. A patch may use the same module more than once; each instance is separately addressable and carries its own parameter values and slot fills."
},
"parameterValue": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"value": {
"type": "unknown",
"description": "The value this patch sets the parameter to. A number that is not a whole number is carried as its decimal string — \"0.5\", not 0.5 — because the ATproto data model has no floating-point type and a PDS refuses one. A whole number is an ordinary integer, and a reader turns such a string back into a number. Where the module declares a closed set of values instead, this is one of those strings, and a label that looks like a number stays the label it is."
},
"useDefault": {
"type": "boolean",
"description": "Set where the patch explicitly defers to the module's default rather than recording a value."
}
},
"description": "A value for one of the module's exposed parameters, or an explicit fall-back to the module's declared default."
},
"sampleSlotFill": {
"type": "object",
"required": [
"slotId",
"blob",
"ownerDid"
],
"properties": {
"blob": {
"type": "blob",
"accept": [
"audio/wav"
],
"maxSize": 2097152
},
"slotId": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"ownerDid": {
"type": "string",
"format": "did"
}
}
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1,
"description": "A synth patch: which modules it uses, how they are wired, what their parameters are set to, and how it is played. A patch plus the module records it pins is everything needed to reproduce it."
}