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.
- package/LICENSE +200 -0
- package/NOTICE +28 -0
- package/README.md +147 -0
- package/dist/am4/applicability.d.ts +61 -0
- package/dist/am4/applicability.d.ts.map +1 -0
- package/dist/am4/applicability.js +285 -0
- package/dist/am4/blockTypes.d.ts +43 -0
- package/dist/am4/blockTypes.d.ts.map +1 -0
- package/dist/am4/blockTypes.js +48 -0
- package/dist/am4/cacheEnums.d.ts +46 -0
- package/dist/am4/cacheEnums.d.ts.map +1 -0
- package/dist/am4/cacheEnums.js +734 -0
- package/dist/am4/cacheParams.d.ts +3533 -0
- package/dist/am4/cacheParams.d.ts.map +1 -0
- package/dist/am4/cacheParams.js +1996 -0
- package/dist/am4/editorControlLabels.d.ts +45 -0
- package/dist/am4/editorControlLabels.d.ts.map +1 -0
- package/dist/am4/editorControlLabels.js +15894 -0
- package/dist/am4/index.d.ts +28 -0
- package/dist/am4/index.d.ts.map +1 -0
- package/dist/am4/index.js +31 -0
- package/dist/am4/ir/preset.d.ts +24 -0
- package/dist/am4/ir/preset.d.ts.map +1 -0
- package/dist/am4/ir/preset.js +12 -0
- package/dist/am4/ir/transpile.d.ts +9 -0
- package/dist/am4/ir/transpile.d.ts.map +1 -0
- package/dist/am4/ir/transpile.js +19 -0
- package/dist/am4/locations.d.ts +32 -0
- package/dist/am4/locations.d.ts.map +1 -0
- package/dist/am4/locations.js +58 -0
- package/dist/am4/paramNames.d.ts +55 -0
- package/dist/am4/paramNames.d.ts.map +1 -0
- package/dist/am4/paramNames.js +863 -0
- package/dist/am4/paramNamesGenerated.d.ts +41 -0
- package/dist/am4/paramNamesGenerated.d.ts.map +1 -0
- package/dist/am4/paramNamesGenerated.js +183 -0
- package/dist/am4/parameterBridge.d.ts +46 -0
- package/dist/am4/parameterBridge.d.ts.map +1 -0
- package/dist/am4/parameterBridge.js +300 -0
- package/dist/am4/params.d.ts +9577 -0
- package/dist/am4/params.d.ts.map +1 -0
- package/dist/am4/params.js +4537 -0
- package/dist/am4/setParam.d.ts +414 -0
- package/dist/am4/setParam.d.ts.map +1 -0
- package/dist/am4/setParam.js +819 -0
- package/dist/am4/shared/paramHelpers.d.ts +55 -0
- package/dist/am4/shared/paramHelpers.d.ts.map +1 -0
- package/dist/am4/shared/paramHelpers.js +146 -0
- package/dist/am4/symbolicIds.d.ts +11 -0
- package/dist/am4/symbolicIds.d.ts.map +1 -0
- package/dist/am4/symbolicIds.js +587 -0
- package/dist/am4/typeApplicability.d.ts +39 -0
- package/dist/am4/typeApplicability.d.ts.map +1 -0
- package/dist/am4/typeApplicability.js +466 -0
- package/dist/am4/variantResolverTables.d.ts +51 -0
- package/dist/am4/variantResolverTables.d.ts.map +1 -0
- package/dist/am4/variantResolverTables.js +3128 -0
- package/dist/axe-fx-ii/blockTypes.d.ts +45 -0
- package/dist/axe-fx-ii/blockTypes.d.ts.map +1 -0
- package/dist/axe-fx-ii/blockTypes.js +116 -0
- package/dist/axe-fx-ii/index.d.ts +5 -0
- package/dist/axe-fx-ii/index.d.ts.map +1 -0
- package/dist/axe-fx-ii/index.js +18 -0
- package/dist/axe-fx-ii/paramAliases.d.ts +54 -0
- package/dist/axe-fx-ii/paramAliases.d.ts.map +1 -0
- package/dist/axe-fx-ii/paramAliases.js +146 -0
- package/dist/axe-fx-ii/params.d.ts +11502 -0
- package/dist/axe-fx-ii/params.d.ts.map +1 -0
- package/dist/axe-fx-ii/params.js +2847 -0
- package/dist/axe-fx-ii/setParam.d.ts +560 -0
- package/dist/axe-fx-ii/setParam.d.ts.map +1 -0
- package/dist/axe-fx-ii/setParam.js +888 -0
- package/dist/axe-fx-iii/blockTypes.d.ts +87 -0
- package/dist/axe-fx-iii/blockTypes.d.ts.map +1 -0
- package/dist/axe-fx-iii/blockTypes.js +156 -0
- package/dist/axe-fx-iii/enumOverlay.d.ts +73 -0
- package/dist/axe-fx-iii/enumOverlay.d.ts.map +1 -0
- package/dist/axe-fx-iii/enumOverlay.js +236 -0
- package/dist/axe-fx-iii/index.d.ts +9 -0
- package/dist/axe-fx-iii/index.d.ts.map +1 -0
- package/dist/axe-fx-iii/index.js +20 -0
- package/dist/axe-fx-iii/params.d.ts +179 -0
- package/dist/axe-fx-iii/params.d.ts.map +1 -0
- package/dist/axe-fx-iii/params.js +6913 -0
- package/dist/axe-fx-iii/setParam.d.ts +460 -0
- package/dist/axe-fx-iii/setParam.d.ts.map +1 -0
- package/dist/axe-fx-iii/setParam.js +910 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/shared/checksum.d.ts +10 -0
- package/dist/shared/checksum.d.ts.map +1 -0
- package/dist/shared/checksum.js +14 -0
- package/dist/shared/device.d.ts +195 -0
- package/dist/shared/device.d.ts.map +1 -0
- package/dist/shared/device.js +27 -0
- package/dist/shared/index.d.ts +8 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +11 -0
- package/dist/shared/lineage/amp-lineage.json +8313 -0
- package/dist/shared/lineage/axefx2-amp-lineage.json +5871 -0
- package/dist/shared/lineage/axefx2-delay-lineage.json +226 -0
- package/dist/shared/lineage/axefx2-drive-lineage.json +575 -0
- package/dist/shared/lineage/axefx2-reverb-lineage.json +467 -0
- package/dist/shared/lineage/cab-lineage.json +10777 -0
- package/dist/shared/lineage/chorus-lineage.json +173 -0
- package/dist/shared/lineage/compressor-lineage.json +338 -0
- package/dist/shared/lineage/delay-lineage.json +313 -0
- package/dist/shared/lineage/drive-lineage.json +1844 -0
- package/dist/shared/lineage/flanger-lineage.json +313 -0
- package/dist/shared/lineage/phaser-lineage.json +208 -0
- package/dist/shared/lineage/reverb-lineage.json +793 -0
- package/dist/shared/lineage/wah-lineage.json +117 -0
- package/dist/shared/lineageLookup.d.ts +69 -0
- package/dist/shared/lineageLookup.d.ts.map +1 -0
- package/dist/shared/lineageLookup.js +196 -0
- package/dist/shared/packValue.d.ts +40 -0
- package/dist/shared/packValue.d.ts.map +1 -0
- package/dist/shared/packValue.js +105 -0
- package/dist/shared/types.d.ts +23 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +9 -0
- 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"}
|