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