at.atmosynth.module
Schema Diff
+17 -0
Compatibility Analysis
Backward Compatible
Backward compatible. 7 non-breaking changes.
Non-Breaking Changes (7)
- AddedVertex AddedVertex { vertex_id: "at.atmosynth.module:body.noteOutputs" }
- AddedVertex AddedVertex { vertex_id: "at.atmosynth.module:body.noteOutputs:items" }
- AddedVertex AddedVertex { vertex_id: "at.atmosynth.module:body.noteSource" }
- AddedEdge AddedEdge { src: "at.atmosynth.module:body", tgt: "at.atmosynth.module:body.noteOutputs", kind: "prop", name: Some("noteOutputs") }
- AddedEdge AddedEdge { src: "at.atmosynth.module:body", tgt: "at.atmosynth.module:body.noteSource", kind: "prop", name: Some("noteSource") }
- AddedEdge AddedEdge { src: "at.atmosynth.module:body.noteOutputs", tgt: "at.atmosynth.module:body.noteOutputs:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "at.atmosynth.module:body.noteOutputs:items", tgt: "at.atmosynth.module#port", kind: "ref", name: None }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "at.atmosynth.module:body.noteOutputs" }AddedVertex { vertex_id: "at.atmosynth.module:body.noteOutputs:items" }AddedVertex { vertex_id: "at.atmosynth.module:body.noteSource" }
Additional Notes
- Non-breaking: AddedEdge { src: "at.atmosynth.module:body", tgt: "at.atmosynth.module:body.noteOutputs", kind: "prop", name: Some("noteOutputs") }
- Non-breaking: AddedEdge { src: "at.atmosynth.module:body", tgt: "at.atmosynth.module:body.noteSource", kind: "prop", name: Some("noteSource") }
- Non-breaking: AddedEdge { src: "at.atmosynth.module:body.noteOutputs", tgt: "at.atmosynth.module:body.noteOutputs:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "at.atmosynth.module:body.noteOutputs:items", tgt: "at.atmosynth.module#port", kind: "ref", name: None }
1
1
{
2
2
"id": "at.atmosynth.module",
3
3
"defs": {
4
4
"main": {
5
5
"key": "tid",
6
6
"type": "record",
7
7
"record": {
8
8
"type": "object",
9
9
"required": [
10
10
"descriptionVersion",
11
11
"moduleId",
12
12
"name",
13
13
"description",
14
14
"audioInputs",
15
15
"audioOutputs",
16
16
"midiInputs",
17
17
"nodes",
18
18
"connections",
19
19
"createdAt"
20
20
],
21
21
"properties": {
22
22
"name": {
23
23
"type": "string",
24
24
"maxLength": 200,
25
25
"minLength": 1
26
26
},
27
27
"nodes": {
28
28
"type": "array",
29
29
"items": {
30
30
"ref": "#node",
31
31
"type": "ref"
32
32
}
33
33
},
34
34
"moduleId": {
35
35
"type": "string",
36
36
"maxLength": 128,
37
37
"description": "Stable identity shared by every published version of this module."
38
38
},
39
39
"createdAt": {
40
40
"type": "string",
41
41
"format": "datetime"
42
42
},
43
43
"automation": {
44
44
"type": "array",
45
45
"items": {
46
46
"ref": "#automation",
47
47
"type": "ref"
48
48
},
49
49
"description": "Scheduled AudioParam envelopes. Web Audio has no envelope node, so these are their own structure."
50
50
},
51
51
"forkedFrom": {
52
52
"ref": "#lineage",
53
53
"type": "ref"
54
54
},
55
55
"midiInputs": {
56
56
"type": "array",
57
57
"items": {
58
58
"ref": "#port",
59
59
"type": "ref"
60
60
}
61
61
},
62
+
"noteSource": {
63
+
"type": "string",
64
+
"maxLength": 64,
65
+
"description": "What this module emits notes by, where it is not made of Web Audio nodes at all. A note source has no `nodes` and no `connections`: it produces note events, and the behaviour that produces them is named here rather than described, because there is no vocabulary of nodes for a thing that makes no sound. A reader that does not know the named behaviour cannot run the module, and says so rather than guessing.",
66
+
"knownValues": [
67
+
"keyboard",
68
+
"sequencer"
69
+
]
70
+
},
62
71
"parameters": {
63
72
"type": "array",
64
73
"items": {
65
74
"ref": "#parameter",
66
75
"type": "ref"
67
76
}
68
77
},
69
78
"versionKey": {
70
79
"type": "string",
71
80
"maxLength": 128,
72
81
"description": "This record's own key within the series. Informational; the record key is authoritative."
73
82
},
74
83
"audioInputs": {
75
84
"type": "array",
76
85
"items": {
77
86
"ref": "#port",
78
87
"type": "ref"
79
88
},
80
89
"description": "Zero or more individually identified audio inputs."
81
90
},
82
91
"connections": {
83
92
"type": "array",
84
93
"items": {
85
94
"ref": "#connection",
86
95
"type": "ref"
87
96
}
88
97
},
89
98
"description": {
90
99
"type": "string",
91
100
"maxLength": 3000
92
101
},
102
+
"noteOutputs": {
103
+
"type": "array",
104
+
"items": {
105
+
"ref": "#port",
106
+
"type": "ref"
107
+
},
108
+
"description": "Zero or more note outputs. A note output carries note events — what is played, and when — rather than a signal, so it is wired to another instance's MIDI input rather than to an audio input. A module that declares one is a source of what is played; a module that declares none is what plays it."
109
+
},
93
110
"sampleSlots": {
94
111
"type": "array",
95
112
"items": {
96
113
"ref": "#sampleSlot",
97
114
"type": "ref"
98
115
}
99
116
},
100
117
"audioOutputs": {
101
118
"type": "array",
102
119
"items": {
103
120
"ref": "#port",
104
121
"type": "ref"
105
122
}
106
123
},
107
124
"descriptionVersion": {
108
125
"type": "integer",
109
126
"minimum": 1,
110
127
"description": "Version of the module description this record follows. A reader accepts any version at or below its own."
111
128
}
112
129
}
113
130
},
114
131
"description": "A module, held in its author's own repository."
115
132
},
116
133
"node": {
117
134
"type": "object",
118
135
"required": [
119
136
"id",
120
137
"kind"
121
138
],
122
139
"properties": {
123
140
"id": {
124
141
"type": "string",
125
142
"maxLength": 64,
126
143
"minLength": 1
127
144
},
128
145
"kind": {
129
146
"type": "string",
130
147
"maxLength": 64,
131
148
"minLength": 1
132
149
},
133
150
"options": {
134
151
"type": "unknown",
135
152
"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."
136
153
}
137
154
},
138
155
"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."
139
156
},
140
157
"port": {
141
158
"type": "object",
142
159
"required": [
143
160
"id"
144
161
],
145
162
"properties": {
146
163
"id": {
147
164
"type": "string",
148
165
"maxLength": 64,
149
166
"minLength": 1
150
167
},
151
168
"label": {
152
169
"type": "string",
153
170
"maxLength": 200
154
171
}
155
172
},
156
173
"description": "One individually identified audio or MIDI boundary of the module."
157
174
},
158
175
"range": {
159
176
"type": "object",
160
177
"required": [
161
178
"min",
162
179
"max"
163
180
],
164
181
"properties": {
165
182
"max": {
166
183
"type": "unknown",
167
184
"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."
168
185
},
169
186
"min": {
170
187
"type": "unknown",
171
188
"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."
172
189
}
173
190
}
174
191
},
175
192
"source": {
176
193
"type": "object",
177
194
"required": [
178
195
"node"
179
196
],
180
197
"properties": {
181
198
"node": {
182
199
"type": "string",
183
200
"maxLength": 64,
184
201
"minLength": 1
185
202
},
186
203
"output": {
187
204
"type": "integer",
188
205
"minimum": 0
189
206
}
190
207
}
191
208
},
192
209
"target": {
193
210
"type": "object",
194
211
"required": [
195
212
"node"
196
213
],
197
214
"properties": {
198
215
"node": {
199
216
"type": "string",
200
217
"maxLength": 64,
201
218
"minLength": 1
202
219
},
203
220
"input": {
204
221
"type": "integer",
205
222
"minimum": 0
206
223
},
207
224
"param": {
208
225
"type": "string",
209
226
"maxLength": 64
210
227
}
211
228
},
212
229
"description": "Exactly one of `input` or `param` is present. `param` is modulation: a node output reaching a named AudioParam."
213
230
},
214
231
"lineage": {
215
232
"type": "object",
216
233
"required": [
217
234
"uri",
218
235
"authorDid"
219
236
],
220
237
"properties": {
221
238
"uri": {
222
239
"type": "string",
223
240
"format": "at-uri"
224
241
},
225
242
"moduleId": {
226
243
"type": "string",
227
244
"maxLength": 128
228
245
},
229
246
"authorDid": {
230
247
"type": "string",
231
248
"format": "did"
232
249
}
233
250
},
234
251
"description": "The module this one was forked from, and its author."
235
252
},
236
253
"parameter": {
237
254
"type": "object",
238
255
"required": [
239
256
"id",
240
257
"label",
241
258
"targets"
242
259
],
243
260
"properties": {
244
261
"id": {
245
262
"type": "string",
246
263
"maxLength": 64,
247
264
"minLength": 1
248
265
},
249
266
"label": {
250
267
"type": "string",
251
268
"maxLength": 200,
252
269
"minLength": 1
253
270
},
254
271
"range": {
255
272
"ref": "#range",
256
273
"type": "ref"
257
274
},
258
275
"values": {
259
276
"type": "array",
260
277
"items": {
261
278
"type": "string",
262
279
"maxLength": 200
263
280
},
264
281
"description": "A closed value set, where the parameter is not numeric."
265
282
},
266
283
"default": {
267
284
"type": "unknown",
268
285
"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."
269
286
},
270
287
"targets": {
271
288
"type": "array",
272
289
"items": {
273
290
"ref": "#parameterTarget",
274
291
"type": "ref"
275
292
},
276
293
"minLength": 1
277
294
}
278
295
},
279
296
"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."
280
297
},
281
298
"sampleRef": {
282
299
"type": "object",
283
300
"required": [
284
301
"blob",
285
302
"ownerDid"
286
303
],
287
304
"properties": {
288
305
"blob": {
289
306
"type": "blob",
290
307
"accept": [
291
308
"audio/wav"
292
309
],
293
310
"maxSize": 2097152
294
311
},
295
312
"ownerDid": {
296
313
"type": "string",
297
314
"format": "did"
298
315
}
299
316
},
300
317
"description": "A sample blob and the account that holds it."
301
318
},
302
319
"automation": {
303
320
"type": "object",
304
321
"required": [
305
322
"id",
306
323
"target",
307
324
"breakpoints"
308
325
],
309
326
"properties": {
310
327
"id": {
311
328
"type": "string",
312
329
"maxLength": 64,
313
330
"minLength": 1
314
331
},
315
332
"label": {
316
333
"type": "string",
317
334
"maxLength": 200
318
335
},
319
336
"target": {
320
337
"ref": "#paramTarget",
321
338
"type": "ref"
322
339
},
323
340
"sustainAt": {
324
341
"type": "integer",
325
342
"minimum": 0,
326
343
"description": "Index into breakpoints where the value holds while a note is held. Absent means a one-shot."
327
344
},
328
345
"breakpoints": {
329
346
"type": "array",
330
347
"items": {
331
348
"ref": "#breakpoint",
332
349
"type": "ref"
333
350
},
334
351
"minLength": 1
335
352
}
336
353
},
337
354
"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."
338
355
},
339
356
"breakpoint": {
340
357
"type": "object",
341
358
"required": [
342
359
"time",
343
360
"value"
344
361
],
345
362
"properties": {
346
363
"time": {
347
364
"type": "integer",
348
365
"minimum": 0,
349
366
"description": "Milliseconds from the trigger."
350
367
},
351
368
"curve": {
352
369
"type": "string",
353
370
"description": "How the value travels from the previous breakpoint.",
354
371
"knownValues": [
355
372
"step",
356
373
"linear",
357
374
"exponential"
358
375
]
359
376
},
360
377
"value": {
361
378
"type": "unknown",
362
379
"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."
363
380
}
364
381
}
365
382
},
366
383
"connection": {
367
384
"type": "object",
368
385
"required": [
369
386
"from",
370
387
"to"
371
388
],
372
389
"properties": {
373
390
"to": {
374
391
"ref": "#target",
375
392
"type": "ref"
376
393
},
377
394
"from": {
378
395
"ref": "#source",
379
396
"type": "ref"
380
397
}
381
398
},
382
399
"description": "An audio connection from a node output to either an audio input or a named AudioParam."
383
400
},
384
401
"sampleSlot": {
385
402
"type": "object",
386
403
"required": [
387
404
"id",
388
405
"node",
389
406
"property"
390
407
],
391
408
"properties": {
392
409
"id": {
393
410
"type": "string",
394
411
"maxLength": 64,
395
412
"minLength": 1
396
413
},
397
414
"node": {
398
415
"type": "string",
399
416
"maxLength": 64,
400
417
"minLength": 1
401
418
},
402
419
"label": {
403
420
"type": "string",
404
421
"maxLength": 200
405
422
},
406
423
"default": {
407
424
"ref": "#sampleRef",
408
425
"type": "ref"
409
426
},
410
427
"property": {
411
428
"type": "string",
412
429
"knownValues": [
413
430
"buffer"
414
431
]
415
432
}
416
433
},
417
434
"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."
418
435
},
419
436
"paramTarget": {
420
437
"type": "object",
421
438
"required": [
422
439
"node",
423
440
"param"
424
441
],
425
442
"properties": {
426
443
"node": {
427
444
"type": "string",
428
445
"maxLength": 64,
429
446
"minLength": 1
430
447
},
431
448
"param": {
432
449
"type": "string",
433
450
"maxLength": 64,
434
451
"minLength": 1
435
452
}
436
453
}
437
454
},
438
455
"parameterTarget": {
439
456
"type": "object",
440
457
"properties": {
441
458
"node": {
442
459
"type": "string",
443
460
"maxLength": 64
444
461
},
445
462
"field": {
446
463
"type": "string",
447
464
"knownValues": [
448
465
"time",
449
466
"value"
450
467
]
451
468
},
452
469
"param": {
453
470
"type": "string",
454
471
"maxLength": 64
455
472
},
456
473
"option": {
457
474
"type": "string",
458
475
"maxLength": 64
459
476
},
460
477
"automation": {
461
478
"type": "string",
462
479
"maxLength": 64
463
480
},
464
481
"breakpoint": {
465
482
"type": "integer",
466
483
"minimum": 0
467
484
}
468
485
},
469
486
"description": "One of: {node, param}, {node, option}, or {automation, breakpoint, field}."
470
487
}
471
488
},
472
489
"$type": "com.atproto.lexicon.schema",
473
490
"lexicon": 1,
474
491
"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."
475
492
}