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