{
"id": "at.atmosynth.module",
"defs": {
"main": {
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"descriptionVersion",
"moduleId",
"name",
"description",
"audioInputs",
"audioOutputs",
"midiInputs",
"nodes",
"connections",
"createdAt"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"nodes": {
"type": "array",
"items": {
"ref": "#node",
"type": "ref"
}
},
"moduleId": {
"type": "string",
"maxLength": 128,
"description": "Stable identity shared by every published version of this module."
},
"createdAt": {
"type": "string",
"format": "datetime"
},
"automation": {
"type": "array",
"items": {
"ref": "#automation",
"type": "ref"
},
"description": "Scheduled AudioParam envelopes. Web Audio has no envelope node, so these are their own structure."
},
"forkedFrom": {
"ref": "#lineage",
"type": "ref"
},
"midiInputs": {
"type": "array",
"items": {
"ref": "#port",
"type": "ref"
}
},
"parameters": {
"type": "array",
"items": {
"ref": "#parameter",
"type": "ref"
}
},
"versionKey": {
"type": "string",
"maxLength": 128,
"description": "This record's own key within the series. Informational; the record key is authoritative."
},
"audioInputs": {
"type": "array",
"items": {
"ref": "#port",
"type": "ref"
},
"description": "Zero or more individually identified audio inputs."
},
"connections": {
"type": "array",
"items": {
"ref": "#connection",
"type": "ref"
}
},
"description": {
"type": "string",
"maxLength": 3000
},
"sampleSlots": {
"type": "array",
"items": {
"ref": "#sampleSlot",
"type": "ref"
}
},
"audioOutputs": {
"type": "array",
"items": {
"ref": "#port",
"type": "ref"
}
},
"descriptionVersion": {
"type": "integer",
"minimum": 1,
"description": "Version of the module description this record follows. A reader accepts any version at or below its own."
}
}
},
"description": "A module, held in its author's own repository."
},
"node": {
"type": "object",
"required": [
"id",
"kind"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"kind": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"options": {
"type": "unknown",
"description": "The node's settings, as its kind defines them. 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."
}
},
"description": "One Web Audio node. `kind` is drawn from a closed vocabulary; `options` are its construction-time settings, which are not AudioParams and cannot be modulated."
},
"port": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 200
}
},
"description": "One individually identified audio or MIDI boundary of the module."
},
"range": {
"type": "object",
"required": [
"min",
"max"
],
"properties": {
"max": {
"type": "unknown",
"description": "The high bound. 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."
},
"min": {
"type": "unknown",
"description": "The low bound. 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."
}
}
},
"source": {
"type": "object",
"required": [
"node"
],
"properties": {
"node": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"output": {
"type": "integer",
"minimum": 0
}
}
},
"target": {
"type": "object",
"required": [
"node"
],
"properties": {
"node": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"input": {
"type": "integer",
"minimum": 0
},
"param": {
"type": "string",
"maxLength": 64
}
},
"description": "Exactly one of `input` or `param` is present. `param` is modulation: a node output reaching a named AudioParam."
},
"lineage": {
"type": "object",
"required": [
"uri",
"authorDid"
],
"properties": {
"uri": {
"type": "string",
"format": "at-uri"
},
"moduleId": {
"type": "string",
"maxLength": 128
},
"authorDid": {
"type": "string",
"format": "did"
}
},
"description": "The module this one was forked from, and its author."
},
"parameter": {
"type": "object",
"required": [
"id",
"label",
"targets"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"range": {
"ref": "#range",
"type": "ref"
},
"values": {
"type": "array",
"items": {
"type": "string",
"maxLength": 200
},
"description": "A closed value set, where the parameter is not numeric."
},
"default": {
"type": "unknown",
"description": "The value used where a patch sets none. 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 this parameter declares a closed value set, it is one of those strings."
},
"targets": {
"type": "array",
"items": {
"ref": "#parameterTarget",
"type": "ref"
},
"minLength": 1
}
},
"description": "A parameter the module exposes for a patch to set. Each target reaches an AudioParam, a construction option, or one field of an automation breakpoint."
},
"sampleRef": {
"type": "object",
"required": [
"blob",
"ownerDid"
],
"properties": {
"blob": {
"type": "blob",
"accept": [
"audio/wav"
],
"maxSize": 2097152
},
"ownerDid": {
"type": "string",
"format": "did"
}
},
"description": "A sample blob and the account that holds it."
},
"automation": {
"type": "object",
"required": [
"id",
"target",
"breakpoints"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 200
},
"target": {
"ref": "#paramTarget",
"type": "ref"
},
"sustainAt": {
"type": "integer",
"minimum": 0,
"description": "Index into breakpoints where the value holds while a note is held. Absent means a one-shot."
},
"breakpoints": {
"type": "array",
"items": {
"ref": "#breakpoint",
"type": "ref"
},
"minLength": 1
}
},
"description": "A breakpoint envelope scheduled onto an AudioParam. Breakpoints up to and including sustainAt are scheduled on note-on; those after it on note-off."
},
"breakpoint": {
"type": "object",
"required": [
"time",
"value"
],
"properties": {
"time": {
"type": "integer",
"minimum": 0,
"description": "Milliseconds from the trigger."
},
"curve": {
"type": "string",
"description": "How the value travels from the previous breakpoint.",
"knownValues": [
"step",
"linear",
"exponential"
]
},
"value": {
"type": "unknown",
"description": "The param's value at this instant. 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."
}
}
},
"connection": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"ref": "#target",
"type": "ref"
},
"from": {
"ref": "#source",
"type": "ref"
}
},
"description": "An audio connection from a node output to either an audio input or a named AudioParam."
},
"sampleSlot": {
"type": "object",
"required": [
"id",
"node",
"property"
],
"properties": {
"id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"node": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 200
},
"default": {
"ref": "#sampleRef",
"type": "ref"
},
"property": {
"type": "string",
"knownValues": [
"buffer"
]
}
},
"description": "A named slot a patch instance may fill with its own sample. `node` names a node in this graph and `property` the thing the sample feeds."
},
"paramTarget": {
"type": "object",
"required": [
"node",
"param"
],
"properties": {
"node": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"param": {
"type": "string",
"maxLength": 64,
"minLength": 1
}
}
},
"parameterTarget": {
"type": "object",
"properties": {
"node": {
"type": "string",
"maxLength": 64
},
"field": {
"type": "string",
"knownValues": [
"time",
"value"
]
},
"param": {
"type": "string",
"maxLength": 64
},
"option": {
"type": "string",
"maxLength": 64
},
"automation": {
"type": "string",
"maxLength": 64
},
"breakpoint": {
"type": "integer",
"minimum": 0
}
},
"description": "One of: {node, param}, {node, option}, or {automation, breakpoint, field}."
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1,
"description": "A reusable synth module: Web Audio nodes wired together, with declared audio and MIDI boundaries, exposed parameters, automation and sample slots. Each published version is its own record; records sharing a moduleId form a series."
}