fractal-midi 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +200 -0
  2. package/NOTICE +28 -0
  3. package/README.md +147 -0
  4. package/dist/am4/applicability.d.ts +61 -0
  5. package/dist/am4/applicability.d.ts.map +1 -0
  6. package/dist/am4/applicability.js +285 -0
  7. package/dist/am4/blockTypes.d.ts +43 -0
  8. package/dist/am4/blockTypes.d.ts.map +1 -0
  9. package/dist/am4/blockTypes.js +48 -0
  10. package/dist/am4/cacheEnums.d.ts +46 -0
  11. package/dist/am4/cacheEnums.d.ts.map +1 -0
  12. package/dist/am4/cacheEnums.js +734 -0
  13. package/dist/am4/cacheParams.d.ts +3533 -0
  14. package/dist/am4/cacheParams.d.ts.map +1 -0
  15. package/dist/am4/cacheParams.js +1996 -0
  16. package/dist/am4/editorControlLabels.d.ts +45 -0
  17. package/dist/am4/editorControlLabels.d.ts.map +1 -0
  18. package/dist/am4/editorControlLabels.js +15894 -0
  19. package/dist/am4/index.d.ts +28 -0
  20. package/dist/am4/index.d.ts.map +1 -0
  21. package/dist/am4/index.js +31 -0
  22. package/dist/am4/ir/preset.d.ts +24 -0
  23. package/dist/am4/ir/preset.d.ts.map +1 -0
  24. package/dist/am4/ir/preset.js +12 -0
  25. package/dist/am4/ir/transpile.d.ts +9 -0
  26. package/dist/am4/ir/transpile.d.ts.map +1 -0
  27. package/dist/am4/ir/transpile.js +19 -0
  28. package/dist/am4/locations.d.ts +32 -0
  29. package/dist/am4/locations.d.ts.map +1 -0
  30. package/dist/am4/locations.js +58 -0
  31. package/dist/am4/paramNames.d.ts +55 -0
  32. package/dist/am4/paramNames.d.ts.map +1 -0
  33. package/dist/am4/paramNames.js +863 -0
  34. package/dist/am4/paramNamesGenerated.d.ts +41 -0
  35. package/dist/am4/paramNamesGenerated.d.ts.map +1 -0
  36. package/dist/am4/paramNamesGenerated.js +183 -0
  37. package/dist/am4/parameterBridge.d.ts +46 -0
  38. package/dist/am4/parameterBridge.d.ts.map +1 -0
  39. package/dist/am4/parameterBridge.js +300 -0
  40. package/dist/am4/params.d.ts +9577 -0
  41. package/dist/am4/params.d.ts.map +1 -0
  42. package/dist/am4/params.js +4537 -0
  43. package/dist/am4/setParam.d.ts +414 -0
  44. package/dist/am4/setParam.d.ts.map +1 -0
  45. package/dist/am4/setParam.js +819 -0
  46. package/dist/am4/shared/paramHelpers.d.ts +55 -0
  47. package/dist/am4/shared/paramHelpers.d.ts.map +1 -0
  48. package/dist/am4/shared/paramHelpers.js +146 -0
  49. package/dist/am4/symbolicIds.d.ts +11 -0
  50. package/dist/am4/symbolicIds.d.ts.map +1 -0
  51. package/dist/am4/symbolicIds.js +587 -0
  52. package/dist/am4/typeApplicability.d.ts +39 -0
  53. package/dist/am4/typeApplicability.d.ts.map +1 -0
  54. package/dist/am4/typeApplicability.js +466 -0
  55. package/dist/am4/variantResolverTables.d.ts +51 -0
  56. package/dist/am4/variantResolverTables.d.ts.map +1 -0
  57. package/dist/am4/variantResolverTables.js +3128 -0
  58. package/dist/axe-fx-ii/blockTypes.d.ts +45 -0
  59. package/dist/axe-fx-ii/blockTypes.d.ts.map +1 -0
  60. package/dist/axe-fx-ii/blockTypes.js +116 -0
  61. package/dist/axe-fx-ii/index.d.ts +5 -0
  62. package/dist/axe-fx-ii/index.d.ts.map +1 -0
  63. package/dist/axe-fx-ii/index.js +18 -0
  64. package/dist/axe-fx-ii/paramAliases.d.ts +54 -0
  65. package/dist/axe-fx-ii/paramAliases.d.ts.map +1 -0
  66. package/dist/axe-fx-ii/paramAliases.js +146 -0
  67. package/dist/axe-fx-ii/params.d.ts +11502 -0
  68. package/dist/axe-fx-ii/params.d.ts.map +1 -0
  69. package/dist/axe-fx-ii/params.js +2847 -0
  70. package/dist/axe-fx-ii/setParam.d.ts +560 -0
  71. package/dist/axe-fx-ii/setParam.d.ts.map +1 -0
  72. package/dist/axe-fx-ii/setParam.js +888 -0
  73. package/dist/axe-fx-iii/blockTypes.d.ts +87 -0
  74. package/dist/axe-fx-iii/blockTypes.d.ts.map +1 -0
  75. package/dist/axe-fx-iii/blockTypes.js +156 -0
  76. package/dist/axe-fx-iii/enumOverlay.d.ts +73 -0
  77. package/dist/axe-fx-iii/enumOverlay.d.ts.map +1 -0
  78. package/dist/axe-fx-iii/enumOverlay.js +236 -0
  79. package/dist/axe-fx-iii/index.d.ts +9 -0
  80. package/dist/axe-fx-iii/index.d.ts.map +1 -0
  81. package/dist/axe-fx-iii/index.js +20 -0
  82. package/dist/axe-fx-iii/params.d.ts +179 -0
  83. package/dist/axe-fx-iii/params.d.ts.map +1 -0
  84. package/dist/axe-fx-iii/params.js +6913 -0
  85. package/dist/axe-fx-iii/setParam.d.ts +460 -0
  86. package/dist/axe-fx-iii/setParam.d.ts.map +1 -0
  87. package/dist/axe-fx-iii/setParam.js +910 -0
  88. package/dist/index.d.ts +2 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +12 -0
  91. package/dist/shared/checksum.d.ts +10 -0
  92. package/dist/shared/checksum.d.ts.map +1 -0
  93. package/dist/shared/checksum.js +14 -0
  94. package/dist/shared/device.d.ts +195 -0
  95. package/dist/shared/device.d.ts.map +1 -0
  96. package/dist/shared/device.js +27 -0
  97. package/dist/shared/index.d.ts +8 -0
  98. package/dist/shared/index.d.ts.map +1 -0
  99. package/dist/shared/index.js +11 -0
  100. package/dist/shared/lineage/amp-lineage.json +8313 -0
  101. package/dist/shared/lineage/axefx2-amp-lineage.json +5871 -0
  102. package/dist/shared/lineage/axefx2-delay-lineage.json +226 -0
  103. package/dist/shared/lineage/axefx2-drive-lineage.json +575 -0
  104. package/dist/shared/lineage/axefx2-reverb-lineage.json +467 -0
  105. package/dist/shared/lineage/cab-lineage.json +10777 -0
  106. package/dist/shared/lineage/chorus-lineage.json +173 -0
  107. package/dist/shared/lineage/compressor-lineage.json +338 -0
  108. package/dist/shared/lineage/delay-lineage.json +313 -0
  109. package/dist/shared/lineage/drive-lineage.json +1844 -0
  110. package/dist/shared/lineage/flanger-lineage.json +313 -0
  111. package/dist/shared/lineage/phaser-lineage.json +208 -0
  112. package/dist/shared/lineage/reverb-lineage.json +793 -0
  113. package/dist/shared/lineage/wah-lineage.json +117 -0
  114. package/dist/shared/lineageLookup.d.ts +69 -0
  115. package/dist/shared/lineageLookup.d.ts.map +1 -0
  116. package/dist/shared/lineageLookup.js +196 -0
  117. package/dist/shared/packValue.d.ts +40 -0
  118. package/dist/shared/packValue.d.ts.map +1 -0
  119. package/dist/shared/packValue.js +105 -0
  120. package/dist/shared/types.d.ts +23 -0
  121. package/dist/shared/types.d.ts.map +1 -0
  122. package/dist/shared/types.js +9 -0
  123. package/package.json +75 -0
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Per-(block, name) applicability helpers — translates the
3
+ * `typeApplicability.ts` generated data into agent-facing prose and
4
+ * runtime predicates.
5
+ *
6
+ * Used by `list_params` to annotate each parameter row with which
7
+ * AM4 types expose it, by `set_param` to warn when the agent writes
8
+ * a knob that the active type doesn't expose, and by `apply_preset`
9
+ * to surface type/param mismatches before any wire bytes are sent.
10
+ */
11
+ import { AMP_TYPES, CHORUS_TYPES, COMPRESSOR_TYPES, DELAY_TYPES, DRIVE_TYPES, FILTER_TYPES, FLANGER_TYPES, GATE_TYPES, GEQ_TYPES, PHASER_TYPES, REVERB_TYPES, TREMOLO_TYPES, } from './cacheEnums.js';
12
+ import { TYPE_APPLICABILITY, } from './typeApplicability.js';
13
+ /**
14
+ * AM4-Edit symbolic enum name → display name array (cacheEnums).
15
+ * Enums not listed here are surfaced as raw indices in agent-facing
16
+ * prose. The omitted ones (CABINET_MODE, DISTORT_MODE_1,
17
+ * DISTORT_EQTYPE, REVERB_SPRINGTYPE, REVERB_LOWSLOPE,
18
+ * REVERB_HIGHSLOPE, PEQ_TYPE1, PEQ_TYPE5) are sub-mode enums whose
19
+ * display names we haven't extracted yet — usable as raw indices in
20
+ * the meantime, easy to add when needed.
21
+ */
22
+ const ENUM_LOOKUP = {
23
+ DISTORT_TYPE: AMP_TYPES,
24
+ AMP_TYPE: AMP_TYPES,
25
+ FUZZ_TYPE: DRIVE_TYPES,
26
+ REVERB_TYPE: REVERB_TYPES,
27
+ REVERB_BASETYPE: REVERB_TYPES,
28
+ DELAY_TYPE: DELAY_TYPES,
29
+ DELAY_MODEL: DELAY_TYPES,
30
+ CHORUS_TYPE: CHORUS_TYPES,
31
+ FLANGER_TYPE: FLANGER_TYPES,
32
+ PHASER_TYPE: PHASER_TYPES,
33
+ TREMOLO_TYPE: TREMOLO_TYPES,
34
+ COMP_TYPE: COMPRESSOR_TYPES,
35
+ FILTER_TYPE: FILTER_TYPES,
36
+ GEQ_TYPE: GEQ_TYPES,
37
+ GATE_TYPE: GATE_TYPES,
38
+ };
39
+ export function getApplicability(blockDotName) {
40
+ return TYPE_APPLICABILITY[blockDotName];
41
+ }
42
+ /**
43
+ * Render a type-enum gate's values as comma-joined display names. Falls
44
+ * back to `idx N` for enums we don't have a cacheEnums lookup for.
45
+ */
46
+ function renderTypeNames(gate) {
47
+ const list = ENUM_LOOKUP[gate.typeEnum] ?? [];
48
+ return gate.values.map((v) => list[v] ?? `idx ${v}`).join(', ');
49
+ }
50
+ /**
51
+ * One-line summary of a parameter's applicability for the agent — appears
52
+ * in `list_params` row decoration. Returns `undefined` for the common
53
+ * "no applicability data" case (out-of-band registers, params not yet
54
+ * decoded by the type-applicability extractor) — caller should treat as
55
+ * always-on. Empty string for confirmed-always-on with no special-case
56
+ * gates (no decoration needed).
57
+ */
58
+ export function describeApplicability(blockDotName) {
59
+ const a = TYPE_APPLICABILITY[blockDotName];
60
+ if (!a)
61
+ return undefined;
62
+ if (a.always && a.gates.length === 0)
63
+ return '';
64
+ if (a.always) {
65
+ // Always-on PLUS special-case pages (e.g. amp.negative_feedback has
66
+ // a Friedman BE special page in addition to the universal one).
67
+ // Surface the special cases as informational; agent doesn't need to
68
+ // gate writes on them.
69
+ const cases = a.gates.map((g) => `${g.typeEnum}=[${renderTypeNames(g)}]`).join('; ');
70
+ return `applies to any type (special-cased on: ${cases})`;
71
+ }
72
+ // Strictly type-gated. Surface the union of types that expose it.
73
+ const cases = a.gates.map((g) => `${g.typeEnum}=[${renderTypeNames(g)}]`).join(' OR ');
74
+ return `applies only when ${cases}`;
75
+ }
76
+ export function checkApplicability(blockDotName, ctx) {
77
+ const a = TYPE_APPLICABILITY[blockDotName];
78
+ if (!a)
79
+ return { applicable: 'unknown' };
80
+ // Truly universal — no gates at all → applies to every type.
81
+ if (a.gates.length === 0) {
82
+ return a.always ? { applicable: true } : { applicable: 'unknown' };
83
+ }
84
+ // 2026-05-13 founder-test correction. Original interpretation: if
85
+ // `a.always === true`, the param applies on every type regardless of
86
+ // gates ("gates list is informational, special-case pages only"). The
87
+ // 5F8 Tweed Normal test surfaced that this is wrong for some
88
+ // metadata-extracted params — amp.master shows `always: true` with a
89
+ // large primary-type gates list, but the gates list is the AUTHORITATIVE
90
+ // set of types that expose the param. Wire 185 (5F8 Tweed Normal) is
91
+ // not in the master gates list; the AM4 silently no-ops master writes
92
+ // on this amp model. Old interpretation let the write through and
93
+ // claimed success; new interpretation refuses.
94
+ //
95
+ // Concretely: when primary-type gates exist (DISTORT_TYPE / FUZZ_TYPE
96
+ // / etc.), the active type MUST be in the gate list. Sub-mode gates
97
+ // (CABINET_MODE, DISTORT_MODE_1, …) are still informational — we
98
+ // don't track sub-mode state so we can't enforce against them.
99
+ const block = blockDotName.split('.')[0];
100
+ const activeIndex = ctx.currentTypes?.[block];
101
+ if (activeIndex === undefined)
102
+ return { applicable: 'unknown' };
103
+ let hasPrimaryGate = false;
104
+ for (const g of a.gates) {
105
+ if (!isGateForBlock(g.typeEnum, block))
106
+ continue;
107
+ if (!isPrimaryTypeEnum(g.typeEnum, block))
108
+ continue;
109
+ hasPrimaryGate = true;
110
+ if (g.values.includes(activeIndex))
111
+ return { applicable: true };
112
+ }
113
+ if (!hasPrimaryGate) {
114
+ // Only sub-mode gates — can't enforce; treat as applicable if
115
+ // `always: true` (the universal-with-special-pages case) or unknown
116
+ // otherwise (caller's fallback is "let the write through with a
117
+ // warning" — see preflightApplicabilityWarning).
118
+ return a.always ? { applicable: true } : { applicable: 'unknown' };
119
+ }
120
+ // Primary-type gates exist AND the active type is NOT in any of
121
+ // them → the param doesn't apply on this type. Refuse the write
122
+ // rather than letting the device silently no-op it.
123
+ return { applicable: false, gates: a.gates };
124
+ }
125
+ /**
126
+ * find_compatible_types: which `block.type` enum values expose every
127
+ * param in `paramNames`? Used by the unified-surface MCP tool of the
128
+ * same name so the agent can pick a type compatible with the knobs
129
+ * it plans to write, BEFORE apply_preset → no "dropped X param"
130
+ * warning round-trip.
131
+ *
132
+ * Algorithm: start with the full type enum, intersect down per param.
133
+ * Params with no applicability data, or only sub-mode gates (e.g.
134
+ * CABINET_MODE), can't narrow on the primary-type axis — skipped.
135
+ * Params with primary-type gates narrow the accepted-types set to the
136
+ * gate value list.
137
+ *
138
+ * Returns `applicability_known: false` when NONE of the listed params
139
+ * have primary-type gates — caller knows the result is the unfiltered
140
+ * full list and should treat it as "try and see" rather than "these
141
+ * are the only valid choices."
142
+ */
143
+ export function findCompatibleTypes(block, paramNames) {
144
+ const typeEnum = primaryTypeEnumFor(block);
145
+ if (typeEnum === undefined) {
146
+ return {
147
+ compatible_types: [],
148
+ total_types: 0,
149
+ applicability_known: false,
150
+ note: `block "${block}" has no primary type enum`,
151
+ };
152
+ }
153
+ const enumDisplayNames = ENUM_LOOKUP[typeEnum] ?? [];
154
+ if (enumDisplayNames.length === 0) {
155
+ return {
156
+ compatible_types: [],
157
+ total_types: 0,
158
+ applicability_known: false,
159
+ note: `no display names registered for ${typeEnum}`,
160
+ };
161
+ }
162
+ const totalTypes = enumDisplayNames.length;
163
+ let accepted = new Set(Array.from({ length: totalTypes }, (_, i) => i));
164
+ let anyPrimaryGateApplied = false;
165
+ const skippedParams = [];
166
+ for (const paramName of paramNames) {
167
+ const key = `${block}.${paramName}`;
168
+ const a = TYPE_APPLICABILITY[key];
169
+ if (a === undefined) {
170
+ skippedParams.push(`${paramName} (no applicability data — treated as always-on)`);
171
+ continue;
172
+ }
173
+ if (a.always && a.gates.length === 0) {
174
+ continue;
175
+ }
176
+ const exposedHere = new Set();
177
+ let hasPrimaryGate = false;
178
+ for (const g of a.gates) {
179
+ if (g.typeEnum !== typeEnum)
180
+ continue;
181
+ hasPrimaryGate = true;
182
+ for (const v of g.values)
183
+ exposedHere.add(v);
184
+ }
185
+ if (!hasPrimaryGate) {
186
+ skippedParams.push(`${paramName} (only sub-mode gates — not narrowable on primary type)`);
187
+ continue;
188
+ }
189
+ anyPrimaryGateApplied = true;
190
+ accepted = new Set([...accepted].filter((idx) => exposedHere.has(idx)));
191
+ if (accepted.size === 0)
192
+ break;
193
+ }
194
+ const compatibleNames = [...accepted]
195
+ .sort((a, b) => a - b)
196
+ .map((idx) => enumDisplayNames[idx])
197
+ .filter((n) => n !== undefined);
198
+ const note = skippedParams.length > 0
199
+ ? `Skipped from narrowing: ${skippedParams.join('; ')}.`
200
+ : undefined;
201
+ return {
202
+ compatible_types: compatibleNames,
203
+ total_types: totalTypes,
204
+ applicability_known: anyPrimaryGateApplied,
205
+ note,
206
+ };
207
+ }
208
+ /**
209
+ * Primary type enum for each AM4 block — the enum the agent picks via
210
+ * `block.type` and that primary-type applicability gates filter on.
211
+ * Mirrors `isPrimaryTypeEnum` below but returns the enum NAME rather
212
+ * than a boolean (caller uses it to look up the display-name table).
213
+ *
214
+ * Returns undefined for blocks with no primary type enum (e.g. peq,
215
+ * volpan, ingate) — those exist as block_types but don't have a
216
+ * `type` selector knob users can pick.
217
+ */
218
+ function primaryTypeEnumFor(block) {
219
+ switch (block) {
220
+ case 'amp': return 'DISTORT_TYPE';
221
+ case 'drive': return 'FUZZ_TYPE';
222
+ case 'delay': return 'DELAY_TYPE';
223
+ case 'reverb': return 'REVERB_TYPE';
224
+ case 'chorus': return 'CHORUS_TYPE';
225
+ case 'flanger': return 'FLANGER_TYPE';
226
+ case 'phaser': return 'PHASER_TYPE';
227
+ case 'wah': return 'WAH_TYPE';
228
+ case 'compressor': return 'COMP_TYPE';
229
+ case 'geq': return 'GEQ_TYPE';
230
+ case 'filter': return 'FILTER_TYPE';
231
+ case 'tremolo': return 'TREMOLO_TYPE';
232
+ case 'gate': return 'GATE_TYPE';
233
+ default: return undefined;
234
+ }
235
+ }
236
+ /**
237
+ * Whether a typeEnum is the block's primary-type enum (the one we track
238
+ * via `lastKnownType[<block>.type]`). Sub-mode enums (CABINET_MODE,
239
+ * DISTORT_MODE_1, REVERB_BASETYPE, etc.) gate UI exposure but we don't
240
+ * read them after every block-type change, so applicability checks
241
+ * against them must downgrade to 'unknown' instead of firing.
242
+ */
243
+ function isPrimaryTypeEnum(typeEnum, block) {
244
+ switch (block) {
245
+ case 'amp': return typeEnum === 'DISTORT_TYPE' || typeEnum === 'AMP_TYPE';
246
+ case 'drive': return typeEnum === 'FUZZ_TYPE';
247
+ case 'delay': return typeEnum === 'DELAY_TYPE' || typeEnum === 'DELAY_MODEL';
248
+ case 'reverb': return typeEnum === 'REVERB_TYPE';
249
+ case 'chorus': return typeEnum === 'CHORUS_TYPE';
250
+ case 'flanger': return typeEnum === 'FLANGER_TYPE';
251
+ case 'phaser': return typeEnum === 'PHASER_TYPE';
252
+ case 'wah': return typeEnum === 'WAH_TYPE';
253
+ case 'compressor': return typeEnum === 'COMP_TYPE';
254
+ case 'geq': return typeEnum === 'GEQ_TYPE';
255
+ case 'filter': return typeEnum === 'FILTER_TYPE';
256
+ case 'tremolo': return typeEnum === 'TREMOLO_TYPE';
257
+ case 'gate': return typeEnum === 'GATE_TYPE';
258
+ default: return false;
259
+ }
260
+ }
261
+ /**
262
+ * Whether a gate's typeEnum corresponds to a given block. The bulk of
263
+ * gates are intra-block (DELAY_TYPE on delay params, FUZZ_TYPE on drive
264
+ * params), but a few cross over (REVERB_BASETYPE / REVERB_SPRINGTYPE
265
+ * both on reverb params; DISTORT_MODE_1 / CABINET_MODE on amp params).
266
+ */
267
+ function isGateForBlock(typeEnum, block) {
268
+ switch (block) {
269
+ case 'amp': return typeEnum === 'DISTORT_TYPE' || typeEnum === 'AMP_TYPE' || typeEnum === 'DISTORT_MODE_1' || typeEnum === 'DISTORT_EQTYPE' || typeEnum === 'CABINET_MODE';
270
+ case 'drive': return typeEnum === 'FUZZ_TYPE';
271
+ case 'delay': return typeEnum === 'DELAY_TYPE' || typeEnum === 'DELAY_MODEL';
272
+ case 'reverb': return typeEnum === 'REVERB_TYPE' || typeEnum === 'REVERB_BASETYPE' || typeEnum === 'REVERB_SPRINGTYPE' || typeEnum === 'REVERB_LOWSLOPE' || typeEnum === 'REVERB_HIGHSLOPE';
273
+ case 'chorus': return typeEnum === 'CHORUS_TYPE';
274
+ case 'flanger': return typeEnum === 'FLANGER_TYPE';
275
+ case 'phaser': return typeEnum === 'PHASER_TYPE';
276
+ case 'wah': return typeEnum === 'WAH_TYPE';
277
+ case 'compressor': return typeEnum === 'COMP_TYPE';
278
+ case 'geq': return typeEnum === 'GEQ_TYPE';
279
+ case 'peq': return typeEnum === 'PEQ_TYPE1' || typeEnum === 'PEQ_TYPE5';
280
+ case 'filter': return typeEnum === 'FILTER_TYPE';
281
+ case 'tremolo': return typeEnum === 'TREMOLO_TYPE';
282
+ case 'gate': return typeEnum === 'GATE_TYPE';
283
+ default: return false;
284
+ }
285
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * AM4 block-type dictionary.
3
+ *
4
+ * Used by block-placement writes: the AM4 addresses "which block lives in
5
+ * slot N" by writing the target block's own pidLow as a float32 into a
6
+ * dedicated slot register (pidLow=0x00CE, pidHigh=0x0010+slot-1). Passing
7
+ * 0 clears the slot ("none").
8
+ *
9
+ * These pidLows match the addresses used by `KNOWN_PARAMS` in `params.ts`
10
+ * (block.type writes, block.gain writes, etc.) — they're intentionally the
11
+ * same constants, duplicated here only to give block placement a clean
12
+ * dictionary without reaching into the param registry.
13
+ */
14
+ export declare const BLOCK_TYPE_VALUES: {
15
+ readonly none: 0;
16
+ readonly amp: 58;
17
+ readonly compressor: 46;
18
+ readonly geq: 50;
19
+ readonly peq: 54;
20
+ readonly reverb: 66;
21
+ readonly delay: 70;
22
+ readonly chorus: 78;
23
+ readonly flanger: 82;
24
+ readonly rotary: 86;
25
+ readonly phaser: 90;
26
+ readonly wah: 94;
27
+ readonly volpan: 102;
28
+ readonly tremolo: 106;
29
+ readonly filter: 114;
30
+ readonly drive: 118;
31
+ readonly enhancer: 122;
32
+ readonly gate: 146;
33
+ };
34
+ export type BlockTypeName = keyof typeof BLOCK_TYPE_VALUES;
35
+ /** Reverse lookup: wire value (block pidLow) → block name. */
36
+ export declare const BLOCK_NAMES_BY_VALUE: Record<number, BlockTypeName>;
37
+ /**
38
+ * Resolve a user-supplied block identifier to its wire value. Accepts the
39
+ * lowercase block name (case-insensitive) or a numeric pidLow directly.
40
+ * Returns undefined on an unknown name.
41
+ */
42
+ export declare function resolveBlockType(input: string | number): number | undefined;
43
+ //# sourceMappingURL=blockTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blockTypes.d.ts","sourceRoot":"","sources":["../../src/am4/blockTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;CAmBpB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAE3D,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAE9D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAK3E"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * AM4 block-type dictionary.
3
+ *
4
+ * Used by block-placement writes: the AM4 addresses "which block lives in
5
+ * slot N" by writing the target block's own pidLow as a float32 into a
6
+ * dedicated slot register (pidLow=0x00CE, pidHigh=0x0010+slot-1). Passing
7
+ * 0 clears the slot ("none").
8
+ *
9
+ * These pidLows match the addresses used by `KNOWN_PARAMS` in `params.ts`
10
+ * (block.type writes, block.gain writes, etc.) — they're intentionally the
11
+ * same constants, duplicated here only to give block placement a clean
12
+ * dictionary without reaching into the param registry.
13
+ */
14
+ export const BLOCK_TYPE_VALUES = {
15
+ none: 0x0000, // empty slot
16
+ amp: 0x003a,
17
+ compressor: 0x002e,
18
+ geq: 0x0032,
19
+ peq: 0x0036, // pidLow pinned Session 18; no Type enum known
20
+ reverb: 0x0042,
21
+ delay: 0x0046,
22
+ chorus: 0x004e,
23
+ flanger: 0x0052,
24
+ rotary: 0x0056, // pidLow pinned Session 18; no Type enum known
25
+ phaser: 0x005a,
26
+ wah: 0x005e,
27
+ volpan: 0x0066,
28
+ tremolo: 0x006a,
29
+ filter: 0x0072,
30
+ drive: 0x0076,
31
+ enhancer: 0x007a,
32
+ gate: 0x0092,
33
+ };
34
+ /** Reverse lookup: wire value (block pidLow) → block name. */
35
+ export const BLOCK_NAMES_BY_VALUE = Object.fromEntries(Object.entries(BLOCK_TYPE_VALUES).map(([k, v]) => [v, k]));
36
+ /**
37
+ * Resolve a user-supplied block identifier to its wire value. Accepts the
38
+ * lowercase block name (case-insensitive) or a numeric pidLow directly.
39
+ * Returns undefined on an unknown name.
40
+ */
41
+ export function resolveBlockType(input) {
42
+ if (typeof input === 'number')
43
+ return input;
44
+ const norm = input.trim().toLowerCase();
45
+ if (norm in BLOCK_TYPE_VALUES)
46
+ return BLOCK_TYPE_VALUES[norm];
47
+ return undefined;
48
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Generated by scripts/gen-cache-enums.ts — do not hand-edit.
3
+ *
4
+ * Source: AM4-Edit metadata cache (effectDefinitions_15_2p0.cache),
5
+ * parsed by scripts/parse-cache.ts, verified against wire captures
6
+ * by scripts/map-cache-params.ts (Session 15).
7
+ *
8
+ * Each array lists the firmware's effect-type dictionary in wire
9
+ * order. The wire value sent in SET_PARAM (at pidHigh=0x000A of the
10
+ * block's pidLow) is the integer index encoded as a float32.
11
+ */
12
+ export declare const AMP_TYPES: readonly string[];
13
+ export declare const DRIVE_TYPES: readonly string[];
14
+ export declare const REVERB_TYPES: readonly string[];
15
+ export declare const DELAY_TYPES: readonly string[];
16
+ export declare const CHORUS_TYPES: readonly string[];
17
+ export declare const FLANGER_TYPES: readonly string[];
18
+ export declare const PHASER_TYPES: readonly string[];
19
+ export declare const WAH_TYPES: readonly string[];
20
+ export declare const COMPRESSOR_TYPES: readonly string[];
21
+ export declare const GEQ_TYPES: readonly string[];
22
+ export declare const FILTER_TYPES: readonly string[];
23
+ export declare const TREMOLO_TYPES: readonly string[];
24
+ export declare const ENHANCER_TYPES: readonly string[];
25
+ export declare const GATE_TYPES: readonly string[];
26
+ export declare const VOLPAN_MODES: readonly string[];
27
+ export declare const TEMPO_DIVISIONS: readonly string[];
28
+ export declare const LFO_WAVEFORMS: readonly string[];
29
+ export declare const AMP_TYPES_VALUES: Record<number, string>;
30
+ export declare const DRIVE_TYPES_VALUES: Record<number, string>;
31
+ export declare const REVERB_TYPES_VALUES: Record<number, string>;
32
+ export declare const DELAY_TYPES_VALUES: Record<number, string>;
33
+ export declare const CHORUS_TYPES_VALUES: Record<number, string>;
34
+ export declare const FLANGER_TYPES_VALUES: Record<number, string>;
35
+ export declare const PHASER_TYPES_VALUES: Record<number, string>;
36
+ export declare const WAH_TYPES_VALUES: Record<number, string>;
37
+ export declare const COMPRESSOR_TYPES_VALUES: Record<number, string>;
38
+ export declare const GEQ_TYPES_VALUES: Record<number, string>;
39
+ export declare const FILTER_TYPES_VALUES: Record<number, string>;
40
+ export declare const TREMOLO_TYPES_VALUES: Record<number, string>;
41
+ export declare const ENHANCER_TYPES_VALUES: Record<number, string>;
42
+ export declare const GATE_TYPES_VALUES: Record<number, string>;
43
+ export declare const VOLPAN_MODES_VALUES: Record<number, string>;
44
+ export declare const TEMPO_DIVISIONS_VALUES: Record<number, string>;
45
+ export declare const LFO_WAVEFORMS_VALUES: Record<number, string>;
46
+ //# sourceMappingURL=cacheEnums.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cacheEnums.d.ts","sourceRoot":"","sources":["../../src/am4/cacheEnums.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAyP7B,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EA+E/B,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAgFhC,CAAC;AAEX,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EA8B/B,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAqBhC,CAAC;AAEX,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAiCjC,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAkBhC,CAAC;AAEX,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAU7B,CAAC;AAEX,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAoBpC,CAAC;AAEX,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAmB7B,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAmBhC,CAAC;AAEX,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAQjC,CAAC;AAEX,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAIlC,CAAC;AAEX,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EAK9B,CAAC;AAEX,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAGhC,CAAC;AAEX,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAgFnC,CAAC;AAEX,eAAO,MAAM,aAAa,EAAE,SAAS,MAAM,EAWjC,CAAC;AAEX,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAgE,CAAC;AACrH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAkE,CAAC;AACzH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmE,CAAC;AAC3H,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAkE,CAAC;AACzH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmE,CAAC;AAC3H,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAoE,CAAC;AAC7H,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmE,CAAC;AAC3H,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAgE,CAAC;AACrH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAuE,CAAC;AACnI,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAgE,CAAC;AACrH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmE,CAAC;AAC3H,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAoE,CAAC;AAC7H,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAqE,CAAC;AAC/H,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAiE,CAAC;AACvH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmE,CAAC;AAC3H,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAsE,CAAC;AACjI,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAoE,CAAC"}