at.atmosynth.module

atmosynth.at

Schema Diff

+13 -9

From

CID
bafyreifevnggceg...
Indexed At
2026-09-08 07:18 UTC
View this version

To

CID
bafyreibishg657q...
Indexed At
2026-09-09 12:09 UTC
View this version

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#parameter.default", sort: "maxLength", value: "200" }
  • ConstraintAdded ConstraintAdded { vertex_id: "at.atmosynth.module#breakpoint.value", 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" }

Migration Guidance

Constraint Changes

  • 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" }
  • 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" }

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

Compare Other Versions

Lexicon Garden

@