at.atmosynth.module
Schema Diff
+4 -3
Compatibility Analysis
Backward Compatible
No changes detected.
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
+
"description": "Zero or more note inputs. A note input carries note events — what is played, and when — from any note source: a sequencer's note output, or the player, which is the on-screen keys, the computer keyboard and every MIDI device at once. \"MIDI\" is the historical name; nothing arriving here need have come from MIDI."
61
62
},
62
63
"noteSource": {
63
64
"type": "string",
64
65
"maxLength": 64,
65
66
"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
67
"knownValues": [
67
68
"keyboard",
68
69
"sequencer"
69
70
]
70
71
},
71
72
"parameters": {
72
73
"type": "array",
73
74
"items": {
74
75
"ref": "#parameter",
75
76
"type": "ref"
76
77
}
77
78
},
78
79
"versionKey": {
79
80
"type": "string",
80
81
"maxLength": 128,
81
-
"description": "This record's own key within the series. Informational; the record key is authoritative."
82
+
"description": "The record key this version is published under, repeated in the record so a reader holding only the record knows which version it is. A patch's `moduleRef.versionKey` is this value, and it is the record key a reader fetches: a record whose `versionKey` differs from its own key is pinned by the key and misdescribed by this field."
82
83
},
83
84
"audioInputs": {
84
85
"type": "array",
85
86
"items": {
86
87
"ref": "#port",
87
88
"type": "ref"
88
89
},
89
90
"description": "Zero or more individually identified audio inputs."
90
91
},
91
92
"connections": {
92
93
"type": "array",
93
94
"items": {
94
95
"ref": "#connection",
95
96
"type": "ref"
96
97
}
97
98
},
98
99
"description": {
99
100
"type": "string",
100
101
"maxLength": 3000
101
102
},
102
103
"noteOutputs": {
103
104
"type": "array",
104
105
"items": {
105
106
"ref": "#port",
106
107
"type": "ref"
107
108
},
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
+
"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 note input (`midiInputs`) 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
110
},
110
111
"sampleSlots": {
111
112
"type": "array",
112
113
"items": {
113
114
"ref": "#sampleSlot",
114
115
"type": "ref"
115
116
}
116
117
},
117
118
"audioOutputs": {
118
119
"type": "array",
119
120
"items": {
120
121
"ref": "#port",
121
122
"type": "ref"
122
123
}
123
124
},
124
125
"descriptionVersion": {
125
126
"type": "integer",
126
127
"minimum": 1,
127
128
"description": "Version of the module description this record follows. A reader accepts any version at or below its own."
128
129
}
129
130
}
130
131
},
131
132
"description": "A module, held in its author's own repository."
132
133
},
133
134
"node": {
134
135
"type": "object",
135
136
"required": [
136
137
"id",
137
138
"kind"
138
139
],
139
140
"properties": {
140
141
"id": {
141
142
"type": "string",
142
143
"maxLength": 64,
143
144
"minLength": 1
144
145
},
145
146
"kind": {
146
147
"type": "string",
147
148
"maxLength": 64,
148
149
"minLength": 1
149
150
},
150
151
"options": {
151
152
"type": "unknown",
152
153
"description": "The node's settings, as its kind defines them. This is an object — which is the whole of what `unknown` means here — so the data model applies inside it: a whole number is an ordinary integer, and a number that is not a whole number is carried as its decimal string, \"0.5\" rather than 0.5, because the ATproto data model has no floating-point type and a PDS refuses one. That is the one difference from the fields this description types as strings, which have nowhere to put an integer."
153
154
}
154
155
},
155
156
"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."
156
157
},
157
158
"port": {
158
159
"type": "object",
159
160
"required": [
160
161
"id"
161
162
],
162
163
"properties": {
163
164
"id": {
164
165
"type": "string",
165
166
"maxLength": 64,
166
167
"minLength": 1
167
168
},
168
169
"label": {
169
170
"type": "string",
170
171
"maxLength": 200
171
172
}
172
173
},
173
174
"description": "One individually identified audio or MIDI boundary of the module."
174
175
},
175
176
"range": {
176
177
"type": "object",
177
178
"required": [
178
179
"min",
179
180
"max"
180
181
],
181
182
"properties": {
182
183
"max": {
183
184
"type": "string",
184
185
"maxLength": 200,
185
186
"description": "The high bound, as its decimal form — \"20000\", \"0.5\" — because the ATproto data model has no floating-point type and a PDS refuses one. A range is numeric by definition, so a reader turns it back into a number without asking anything else."
186
187
},
187
188
"min": {
188
189
"type": "string",
189
190
"maxLength": 200,
190
191
"description": "The low bound, as its decimal form — \"0.0001\", \"-1\" — because the ATproto data model has no floating-point type and a PDS refuses one. A range is numeric by definition, so a reader turns it back into a number without asking anything else."
191
192
}
192
193
}
193
194
},
194
195
"source": {
195
196
"type": "object",
196
197
"required": [
197
198
"node"
198
199
],
199
200
"properties": {
200
201
"node": {
201
202
"type": "string",
202
203
"maxLength": 64,
203
204
"minLength": 1
204
205
},
205
206
"output": {
206
207
"type": "integer",
207
208
"minimum": 0
208
209
}
209
210
}
210
211
},
211
212
"target": {
212
213
"type": "object",
213
214
"required": [
214
215
"node"
215
216
],
216
217
"properties": {
217
218
"node": {
218
219
"type": "string",
219
220
"maxLength": 64,
220
221
"minLength": 1
221
222
},
222
223
"input": {
223
224
"type": "integer",
224
225
"minimum": 0
225
226
},
226
227
"param": {
227
228
"type": "string",
228
229
"maxLength": 64
229
230
}
230
231
},
231
232
"description": "Exactly one of `input` or `param` is present. `param` is modulation: a node output reaching a named AudioParam."
232
233
},
233
234
"lineage": {
234
235
"type": "object",
235
236
"required": [
236
237
"uri",
237
238
"authorDid"
238
239
],
239
240
"properties": {
240
241
"uri": {
241
242
"type": "string",
242
243
"format": "at-uri"
243
244
},
244
245
"moduleId": {
245
246
"type": "string",
246
247
"maxLength": 128
247
248
},
248
249
"authorDid": {
249
250
"type": "string",
250
251
"format": "did"
251
252
}
252
253
},
253
254
"description": "The module this one was forked from, and its author."
254
255
},
255
256
"parameter": {
256
257
"type": "object",
257
258
"required": [
258
259
"id",
259
260
"label",
260
261
"targets"
261
262
],
262
263
"properties": {
263
264
"id": {
264
265
"type": "string",
265
266
"maxLength": 64,
266
267
"minLength": 1
267
268
},
268
269
"label": {
269
270
"type": "string",
270
271
"maxLength": 200,
271
272
"minLength": 1
272
273
},
273
274
"range": {
274
275
"ref": "#range",
275
276
"type": "ref"
276
277
},
277
278
"values": {
278
279
"type": "array",
279
280
"items": {
280
281
"type": "string",
281
282
"maxLength": 200
282
283
},
283
284
"description": "A closed value set, where the parameter is not numeric."
284
285
},
285
286
"default": {
286
287
"type": "string",
287
288
"maxLength": 200,
288
289
"description": "The value used where a patch sets none, always as text. A number is its decimal form — \"0.5\", and \"2\" for a whole one — because the ATproto data model has no floating-point type and a string is the only type that carries both a number and a word. Where this parameter declares a closed value set, it is one of those strings instead, and a label that looks like a number stays the label it is."
289
290
},
290
291
"targets": {
291
292
"type": "array",
292
293
"items": {
293
294
"ref": "#parameterTarget",
294
295
"type": "ref"
295
296
},
296
297
"minLength": 1
297
298
}
298
299
},
299
300
"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."
300
301
},
301
302
"sampleRef": {
302
303
"type": "object",
303
304
"required": [
304
305
"blob",
305
306
"ownerDid"
306
307
],
307
308
"properties": {
308
309
"blob": {
309
310
"type": "blob",
310
311
"accept": [
311
312
"audio/wav"
312
313
],
313
314
"maxSize": 2097152
314
315
},
315
316
"ownerDid": {
316
317
"type": "string",
317
318
"format": "did"
318
319
}
319
320
},
320
321
"description": "A sample blob and the account that holds it."
321
322
},
322
323
"automation": {
323
324
"type": "object",
324
325
"required": [
325
326
"id",
326
327
"target",
327
328
"breakpoints"
328
329
],
329
330
"properties": {
330
331
"id": {
331
332
"type": "string",
332
333
"maxLength": 64,
333
334
"minLength": 1
334
335
},
335
336
"label": {
336
337
"type": "string",
337
338
"maxLength": 200
338
339
},
339
340
"target": {
340
341
"ref": "#paramTarget",
341
342
"type": "ref"
342
343
},
343
344
"sustainAt": {
344
345
"type": "integer",
345
346
"minimum": 0,
346
347
"description": "Index into breakpoints where the value holds while a note is held. Absent means a one-shot."
347
348
},
348
349
"breakpoints": {
349
350
"type": "array",
350
351
"items": {
351
352
"ref": "#breakpoint",
352
353
"type": "ref"
353
354
},
354
355
"minLength": 1
355
356
}
356
357
},
357
358
"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."
358
359
},
359
360
"breakpoint": {
360
361
"type": "object",
361
362
"required": [
362
363
"time",
363
364
"value"
364
365
],
365
366
"properties": {
366
367
"time": {
367
368
"type": "integer",
368
369
"minimum": 0,
369
370
"description": "Milliseconds from the trigger."
370
371
},
371
372
"curve": {
372
373
"type": "string",
373
374
"description": "How the value travels from the previous breakpoint.",
374
375
"knownValues": [
375
376
"step",
376
377
"linear",
377
378
"exponential"
378
379
]
379
380
},
380
381
"value": {
381
382
"type": "string",
382
383
"maxLength": 200,
383
384
"description": "The param's value at this instant, as its decimal form — \"0.25\", \"1\" — because the ATproto data model has no floating-point type and a PDS refuses one. An automation is numeric by definition, so a reader turns it back into a number without asking anything else."
384
385
}
385
386
}
386
387
},
387
388
"connection": {
388
389
"type": "object",
389
390
"required": [
390
391
"from",
391
392
"to"
392
393
],
393
394
"properties": {
394
395
"to": {
395
396
"ref": "#target",
396
397
"type": "ref"
397
398
},
398
399
"from": {
399
400
"ref": "#source",
400
401
"type": "ref"
401
402
}
402
403
},
403
404
"description": "An audio connection from a node output to either an audio input or a named AudioParam."
404
405
},
405
406
"sampleSlot": {
406
407
"type": "object",
407
408
"required": [
408
409
"id",
409
410
"node",
410
411
"property"
411
412
],
412
413
"properties": {
413
414
"id": {
414
415
"type": "string",
415
416
"maxLength": 64,
416
417
"minLength": 1
417
418
},
418
419
"node": {
419
420
"type": "string",
420
421
"maxLength": 64,
421
422
"minLength": 1
422
423
},
423
424
"label": {
424
425
"type": "string",
425
426
"maxLength": 200
426
427
},
427
428
"default": {
428
429
"ref": "#sampleRef",
429
430
"type": "ref"
430
431
},
431
432
"property": {
432
433
"type": "string",
433
434
"knownValues": [
434
435
"buffer"
435
436
]
436
437
}
437
438
},
438
439
"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."
439
440
},
440
441
"paramTarget": {
441
442
"type": "object",
442
443
"required": [
443
444
"node",
444
445
"param"
445
446
],
446
447
"properties": {
447
448
"node": {
448
449
"type": "string",
449
450
"maxLength": 64,
450
451
"minLength": 1
451
452
},
452
453
"param": {
453
454
"type": "string",
454
455
"maxLength": 64,
455
456
"minLength": 1
456
457
}
457
458
}
458
459
},
459
460
"parameterTarget": {
460
461
"type": "object",
461
462
"properties": {
462
463
"node": {
463
464
"type": "string",
464
465
"maxLength": 64
465
466
},
466
467
"field": {
467
468
"type": "string",
468
469
"knownValues": [
469
470
"time",
470
471
"value"
471
472
]
472
473
},
473
474
"param": {
474
475
"type": "string",
475
476
"maxLength": 64
476
477
},
477
478
"option": {
478
479
"type": "string",
479
480
"maxLength": 64
480
481
},
481
482
"automation": {
482
483
"type": "string",
483
484
"maxLength": 64
484
485
},
485
486
"breakpoint": {
486
487
"type": "integer",
487
488
"minimum": 0
488
489
}
489
490
},
490
491
"description": "One of: {node, param}, {node, option}, or {automation, breakpoint, field}."
491
492
}
492
493
},
493
494
"$type": "com.atproto.lexicon.schema",
494
495
"lexicon": 1,
495
496
"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."
496
497
}