at.atmosynth.module
Schema Diff
+5 -2
Compatibility Analysis
Breaking Changes Detected
1 breaking change, 0 non-breaking changes.
Breaking Changes (1)
- ConstraintTightened ConstraintTightened { vertex_id: "at.atmosynth.module:body.noteSource", sort: "knownValues", old_value: "[\"keyboard\",\"sequencer\"]", new_value: "[\"keyboard\",\"sequencer\",\"range\",\"transpose\",\"assign\"]" }
Migration Guidance
Constraint Changes
- ConstraintTightened ConstraintTightened { vertex_id: "at.atmosynth.module:body.noteSource", sort: "knownValues", old_value: "[\"keyboard\",\"sequencer\"]", new_value: "[\"keyboard\",\"sequencer\",\"range\",\"transpose\",\"assign\"]" }
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
-
"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.",
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. `range` emits none of its own: it passes on the notes wired into its input that fall inside the range its instance names (`noteRange` on the patch's instance), each still the note of whatever played it. `transpose` and `assign` emit none of their own either: they pass on every note wired into their input at another pitch — moved by the semitones the instance names (`transpose`), or at the one note it names (`assignedNote`) — each still the note of whatever played it, and starting and stopping when it did. 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
-
"sequencer"
198
+
"sequencer",
199
+
"range",
200
+
"transpose",
201
+
"assign"
199
202
],
200
203
"maxLength": 64,
201
204
"type": "string"
202
205
},
203
206
"parameters": {
204
207
"items": {
205
208
"ref": "#parameter",
206
209
"type": "ref"
207
210
},
208
211
"type": "array"
209
212
},
210
213
"patternSource": {
211
214
"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
215
"knownValues": [
213
216
"arranger"
214
217
],
215
218
"maxLength": 64,
216
219
"type": "string"
217
220
},
218
221
"sampleSlots": {
219
222
"items": {
220
223
"ref": "#sampleSlot",
221
224
"type": "ref"
222
225
},
223
226
"type": "array"
224
227
},
225
228
"versionKey": {
226
229
"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.",
227
230
"maxLength": 128,
228
231
"type": "string"
229
232
}
230
233
},
231
234
"required": [
232
235
"descriptionVersion",
233
236
"moduleId",
234
237
"name",
235
238
"description",
236
239
"audioInputs",
237
240
"audioOutputs",
238
241
"midiInputs",
239
242
"nodes",
240
243
"connections",
241
244
"createdAt"
242
245
],
243
246
"type": "object"
244
247
},
245
248
"type": "record"
246
249
},
247
250
"node": {
248
251
"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.",
249
252
"properties": {
250
253
"id": {
251
254
"maxLength": 64,
252
255
"minLength": 1,
253
256
"type": "string"
254
257
},
255
258
"kind": {
256
259
"maxLength": 64,
257
260
"minLength": 1,
258
261
"type": "string"
259
262
},
260
263
"options": {
261
264
"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.",
262
265
"type": "unknown"
263
266
}
264
267
},
265
268
"required": [
266
269
"id",
267
270
"kind"
268
271
],
269
272
"type": "object"
270
273
},
271
274
"paramTarget": {
272
275
"properties": {
273
276
"node": {
274
277
"maxLength": 64,
275
278
"minLength": 1,
276
279
"type": "string"
277
280
},
278
281
"param": {
279
282
"maxLength": 64,
280
283
"minLength": 1,
281
284
"type": "string"
282
285
}
283
286
},
284
287
"required": [
285
288
"node",
286
289
"param"
287
290
],
288
291
"type": "object"
289
292
},
290
293
"parameter": {
291
294
"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.",
292
295
"properties": {
293
296
"default": {
294
297
"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.",
295
298
"maxLength": 200,
296
299
"type": "string"
297
300
},
298
301
"id": {
299
302
"maxLength": 64,
300
303
"minLength": 1,
301
304
"type": "string"
302
305
},
303
306
"label": {
304
307
"maxLength": 200,
305
308
"minLength": 1,
306
309
"type": "string"
307
310
},
308
311
"range": {
309
312
"ref": "#range",
310
313
"type": "ref"
311
314
},
312
315
"targets": {
313
316
"items": {
314
317
"ref": "#parameterTarget",
315
318
"type": "ref"
316
319
},
317
320
"minLength": 1,
318
321
"type": "array"
319
322
},
320
323
"values": {
321
324
"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.",
322
325
"items": {
323
326
"maxLength": 200,
324
327
"type": "string"
325
328
},
326
329
"type": "array"
327
330
}
328
331
},
329
332
"required": [
330
333
"id",
331
334
"label",
332
335
"targets"
333
336
],
334
337
"type": "object"
335
338
},
336
339
"parameterTarget": {
337
340
"description": "One of: {node, param}, {node, option}, or {automation, breakpoint, field}.",
338
341
"properties": {
339
342
"automation": {
340
343
"maxLength": 64,
341
344
"type": "string"
342
345
},
343
346
"breakpoint": {
344
347
"minimum": 0,
345
348
"type": "integer"
346
349
},
347
350
"field": {
348
351
"knownValues": [
349
352
"time",
350
353
"value"
351
354
],
352
355
"type": "string"
353
356
},
354
357
"node": {
355
358
"maxLength": 64,
356
359
"type": "string"
357
360
},
358
361
"option": {
359
362
"maxLength": 64,
360
363
"type": "string"
361
364
},
362
365
"param": {
363
366
"maxLength": 64,
364
367
"type": "string"
365
368
}
366
369
},
367
370
"type": "object"
368
371
},
369
372
"port": {
370
373
"description": "One individually identified audio or MIDI boundary of the module.",
371
374
"properties": {
372
375
"id": {
373
376
"maxLength": 64,
374
377
"minLength": 1,
375
378
"type": "string"
376
379
},
377
380
"label": {
378
381
"maxLength": 200,
379
382
"type": "string"
380
383
}
381
384
},
382
385
"required": [
383
386
"id"
384
387
],
385
388
"type": "object"
386
389
},
387
390
"range": {
388
391
"properties": {
389
392
"max": {
390
393
"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.",
391
394
"maxLength": 200,
392
395
"type": "string"
393
396
},
394
397
"min": {
395
398
"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.",
396
399
"maxLength": 200,
397
400
"type": "string"
398
401
}
399
402
},
400
403
"required": [
401
404
"min",
402
405
"max"
403
406
],
404
407
"type": "object"
405
408
},
406
409
"sampleRef": {
407
410
"description": "A sample blob and the account that holds it.",
408
411
"properties": {
409
412
"blob": {
410
413
"accept": [
411
414
"audio/wav"
412
415
],
413
416
"maxSize": 2097152,
414
417
"type": "blob"
415
418
},
416
419
"ownerDid": {
417
420
"format": "did",
418
421
"type": "string"
419
422
}
420
423
},
421
424
"required": [
422
425
"blob",
423
426
"ownerDid"
424
427
],
425
428
"type": "object"
426
429
},
427
430
"sampleSlot": {
428
431
"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.",
429
432
"properties": {
430
433
"default": {
431
434
"ref": "#sampleRef",
432
435
"type": "ref"
433
436
},
434
437
"id": {
435
438
"maxLength": 64,
436
439
"minLength": 1,
437
440
"type": "string"
438
441
},
439
442
"label": {
440
443
"maxLength": 200,
441
444
"type": "string"
442
445
},
443
446
"node": {
444
447
"maxLength": 64,
445
448
"minLength": 1,
446
449
"type": "string"
447
450
},
448
451
"property": {
449
452
"knownValues": [
450
453
"buffer"
451
454
],
452
455
"type": "string"
453
456
}
454
457
},
455
458
"required": [
456
459
"id",
457
460
"node",
458
461
"property"
459
462
],
460
463
"type": "object"
461
464
},
462
465
"source": {
463
466
"properties": {
464
467
"node": {
465
468
"maxLength": 64,
466
469
"minLength": 1,
467
470
"type": "string"
468
471
},
469
472
"output": {
470
473
"minimum": 0,
471
474
"type": "integer"
472
475
}
473
476
},
474
477
"required": [
475
478
"node"
476
479
],
477
480
"type": "object"
478
481
},
479
482
"target": {
480
483
"description": "Exactly one of `input` or `param` is present. `param` is modulation: a node output reaching a named AudioParam.",
481
484
"properties": {
482
485
"input": {
483
486
"minimum": 0,
484
487
"type": "integer"
485
488
},
486
489
"node": {
487
490
"maxLength": 64,
488
491
"minLength": 1,
489
492
"type": "string"
490
493
},
491
494
"param": {
492
495
"maxLength": 64,
493
496
"type": "string"
494
497
}
495
498
},
496
499
"required": [
497
500
"node"
498
501
],
499
502
"type": "object"
500
503
}
501
504
},
502
505
"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.",
503
506
"id": "at.atmosynth.module",
504
507
"lexicon": 1
505
508
}