at.atmosynth.module

atmosynth.at

Schema Diff

+8 -0

From

CID
bafyreibhkca25yx...
Indexed At
2026-09-21 13:47 UTC
View this version

To

CID
bafyreie7vbl2bxf...
Indexed At
2026-09-22 18:36 UTC
View this version

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
}

Compare Other Versions

Lexicon Garden

@