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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axe-Fx III block-type catalog with effect IDs from v1.4 PDF Appendix 1.
|
|
3
|
+
*
|
|
4
|
+
* Effect IDs are 14-bit values used in the `id id` payload position
|
|
5
|
+
* of functions 0x0A (SET_BYPASS), 0x0B (SET_CHANNEL), and the
|
|
6
|
+
* response triples from 0x13 (STATUS_DUMP). Source:
|
|
7
|
+
* `docs/manuals/AxeFx3-MIDI-3rdParty.txt` Appendix 1.
|
|
8
|
+
*
|
|
9
|
+
* Per the PDF, each block-type that supports up to 4 instances has 4
|
|
10
|
+
* consecutive effect IDs (e.g. `ID_COMP1 = 46, ID_COMP2 = 47,
|
|
11
|
+
* ID_COMP3 = 48, ID_COMP4 = 49`). Singletons have one ID. This file
|
|
12
|
+
* exposes the first-instance ID + instance count; resolvers compute
|
|
13
|
+
* `instance_N_id = firstId + (N-1)`.
|
|
14
|
+
*
|
|
15
|
+
* Anomalies / unknowns documented in `docs/SYSEX-MAP-AXE-FX-III.md`:
|
|
16
|
+
* - **AMP is absent from v1.4 Appendix 1.** AMP effect IDs are
|
|
17
|
+
* either in the 3..34 reserved range or deliberately omitted. The
|
|
18
|
+
* AMP block entry below carries `firstId: null` until a STATUS_DUMP
|
|
19
|
+
* against a preset containing AMP decodes its ID.
|
|
20
|
+
* - **Post-firmware-1.13 blocks have no effect ID in the v1.4 PDF**:
|
|
21
|
+
* NAM, Dynamic Distortion, IR Capture (as a block; the Appendix
|
|
22
|
+
* has `ID_IRCAPTURE = 36` for the utility), and recent layouts.
|
|
23
|
+
* These also carry `firstId: null`.
|
|
24
|
+
* - **`ID_DISTORT`** in the PDF maps to what AxeEdit III displays as
|
|
25
|
+
* the **Drive** block (DRV). Same hardware, different name.
|
|
26
|
+
* - **`ID_FUZZ`** is a separate effect-ID range from `ID_DISTORT`,
|
|
27
|
+
* yet AxeEdit III may collapse both under the Drive picker. We
|
|
28
|
+
* model FUZZ as its own catalog entry per the spec.
|
|
29
|
+
*/
|
|
30
|
+
/** Confidence tag for each catalog entry's `firstId`. */
|
|
31
|
+
export type ConfidenceTag = 'spec-v1.4' | 'editor-asset' | 'inferred-from-ii' | 'pending-capture';
|
|
32
|
+
export interface AxeFxIIIBlock {
|
|
33
|
+
/**
|
|
34
|
+
* First-instance effect ID (e.g. ID_REVERB1 = 66). `null` if the
|
|
35
|
+
* block isn't in v1.4 Appendix 1. To address instance N (1-based),
|
|
36
|
+
* compute `firstId + (N - 1)`.
|
|
37
|
+
*/
|
|
38
|
+
firstId: number | null;
|
|
39
|
+
/** Number of instances this block-type supports on the III. */
|
|
40
|
+
instances: number;
|
|
41
|
+
/** Display name as shown in AxeEdit III. */
|
|
42
|
+
name: string;
|
|
43
|
+
/** Three-letter group code Fractal uses internally (AMP, CMP, REV, ...). */
|
|
44
|
+
groupCode: string;
|
|
45
|
+
/** Devices that ship this block; absent = all (III + FM9 + FM3). */
|
|
46
|
+
availability?: 'iii-only' | 'iii+fm9' | 'iii+fm9+fm3' | 'utility-only';
|
|
47
|
+
/** Confidence tag for this entry. */
|
|
48
|
+
confidence: ConfidenceTag;
|
|
49
|
+
/**
|
|
50
|
+
* False when v1.4 lists the effect ID but the block is NOT controllable
|
|
51
|
+
* via the 3rd-party MIDI surface (e.g. internal Control/FC/MIDI blocks
|
|
52
|
+
* that respond to FC interface only). `set_bypass` / `set_channel`
|
|
53
|
+
* refuse with a clean error for these. Defaults to true when absent.
|
|
54
|
+
*
|
|
55
|
+
* Confirmed non-addressable from community RE (forum thread #140602,
|
|
56
|
+
* 2019):
|
|
57
|
+
* - ID_CONTROL (2) → Controllers
|
|
58
|
+
* - ID_MIDIBLOCK (190) → Scene MIDI
|
|
59
|
+
* - ID_FOOTCONTROLLER (199) → Foot Controller
|
|
60
|
+
* - ID_PRESET_FC (200) → Preset FC
|
|
61
|
+
*/
|
|
62
|
+
addressable?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The Axe-Fx III block-type catalog. Order is roughly the order
|
|
66
|
+
* AxeEdit III displays them in its block-picker palette. Effect IDs
|
|
67
|
+
* are from v1.4 Appendix 1 where documented.
|
|
68
|
+
*/
|
|
69
|
+
export declare const AXE_FX_III_BLOCKS: readonly AxeFxIIIBlock[];
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a user-supplied block reference (display name or group code)
|
|
72
|
+
* to its block descriptor. Returns `undefined` if not found.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveBlock(input: string): AxeFxIIIBlock | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Resolve a "block + instance" reference (e.g. "Reverb 1", "Drive 2",
|
|
77
|
+
* "REV 3") to a concrete effect ID. Returns the effect ID, or throws
|
|
78
|
+
* with a helpful message if the block is unknown OR has no effect ID
|
|
79
|
+
* in the v1.4 spec (AMP, NAM, etc.).
|
|
80
|
+
*
|
|
81
|
+
* Accepts both:
|
|
82
|
+
* - `"Reverb 1"` (display name + instance number)
|
|
83
|
+
* - `"REV"` or `"Reverb"` (no instance → defaults to instance 1)
|
|
84
|
+
* - `{ block: 'Reverb', instance: 2 }` (object form, see overload)
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveEffectId(blockName: string, instance?: number): number;
|
|
87
|
+
//# sourceMappingURL=blockTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockTypes.d.ts","sourceRoot":"","sources":["../../src/axe-fx-iii/blockTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,yDAAyD;AACzD,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,cAAc,GACd,kBAAkB,GAClB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,cAAc,CAAC;IACvE,qCAAqC;IACrC,UAAU,EAAE,aAAa,CAAC;IAC1B;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,aAAa,EAoE5C,CAAC;AAcX;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAMrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAuCR"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axe-Fx III block-type catalog with effect IDs from v1.4 PDF Appendix 1.
|
|
3
|
+
*
|
|
4
|
+
* Effect IDs are 14-bit values used in the `id id` payload position
|
|
5
|
+
* of functions 0x0A (SET_BYPASS), 0x0B (SET_CHANNEL), and the
|
|
6
|
+
* response triples from 0x13 (STATUS_DUMP). Source:
|
|
7
|
+
* `docs/manuals/AxeFx3-MIDI-3rdParty.txt` Appendix 1.
|
|
8
|
+
*
|
|
9
|
+
* Per the PDF, each block-type that supports up to 4 instances has 4
|
|
10
|
+
* consecutive effect IDs (e.g. `ID_COMP1 = 46, ID_COMP2 = 47,
|
|
11
|
+
* ID_COMP3 = 48, ID_COMP4 = 49`). Singletons have one ID. This file
|
|
12
|
+
* exposes the first-instance ID + instance count; resolvers compute
|
|
13
|
+
* `instance_N_id = firstId + (N-1)`.
|
|
14
|
+
*
|
|
15
|
+
* Anomalies / unknowns documented in `docs/SYSEX-MAP-AXE-FX-III.md`:
|
|
16
|
+
* - **AMP is absent from v1.4 Appendix 1.** AMP effect IDs are
|
|
17
|
+
* either in the 3..34 reserved range or deliberately omitted. The
|
|
18
|
+
* AMP block entry below carries `firstId: null` until a STATUS_DUMP
|
|
19
|
+
* against a preset containing AMP decodes its ID.
|
|
20
|
+
* - **Post-firmware-1.13 blocks have no effect ID in the v1.4 PDF**:
|
|
21
|
+
* NAM, Dynamic Distortion, IR Capture (as a block; the Appendix
|
|
22
|
+
* has `ID_IRCAPTURE = 36` for the utility), and recent layouts.
|
|
23
|
+
* These also carry `firstId: null`.
|
|
24
|
+
* - **`ID_DISTORT`** in the PDF maps to what AxeEdit III displays as
|
|
25
|
+
* the **Drive** block (DRV). Same hardware, different name.
|
|
26
|
+
* - **`ID_FUZZ`** is a separate effect-ID range from `ID_DISTORT`,
|
|
27
|
+
* yet AxeEdit III may collapse both under the Drive picker. We
|
|
28
|
+
* model FUZZ as its own catalog entry per the spec.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* The Axe-Fx III block-type catalog. Order is roughly the order
|
|
32
|
+
* AxeEdit III displays them in its block-picker palette. Effect IDs
|
|
33
|
+
* are from v1.4 Appendix 1 where documented.
|
|
34
|
+
*/
|
|
35
|
+
export const AXE_FX_III_BLOCKS = [
|
|
36
|
+
// Compositing utilities (singletons, IDs from PDF Appendix)
|
|
37
|
+
{ firstId: 2, instances: 1, name: 'Controllers', groupCode: 'CTR', confidence: 'spec-v1.4', addressable: false },
|
|
38
|
+
// (IDs 3-34 reserved or unenumerated in v1.4)
|
|
39
|
+
{ firstId: 35, instances: 1, name: 'Tuner', groupCode: 'TUN', confidence: 'spec-v1.4' },
|
|
40
|
+
{ firstId: 36, instances: 1, name: 'IR Capture', groupCode: 'IRC', availability: 'utility-only', confidence: 'spec-v1.4' },
|
|
41
|
+
{ firstId: 37, instances: 5, name: 'Input', groupCode: 'IN', confidence: 'spec-v1.4' },
|
|
42
|
+
{ firstId: 42, instances: 4, name: 'Output', groupCode: 'OUT', confidence: 'spec-v1.4' },
|
|
43
|
+
// Signal-chain blocks (4 instances each unless noted)
|
|
44
|
+
{ firstId: 46, instances: 4, name: 'Compressor', groupCode: 'CMP', confidence: 'spec-v1.4' },
|
|
45
|
+
{ firstId: 50, instances: 4, name: 'Graphic EQ', groupCode: 'GEQ', confidence: 'spec-v1.4' },
|
|
46
|
+
{ firstId: 54, instances: 4, name: 'Parametric EQ', groupCode: 'PEQ', confidence: 'spec-v1.4' },
|
|
47
|
+
{ firstId: 58, instances: 4, name: 'Drive', groupCode: 'DRV', confidence: 'spec-v1.4' },
|
|
48
|
+
{ firstId: 62, instances: 4, name: 'Cab', groupCode: 'CAB', confidence: 'spec-v1.4' },
|
|
49
|
+
{ firstId: 66, instances: 4, name: 'Reverb', groupCode: 'REV', confidence: 'spec-v1.4' },
|
|
50
|
+
{ firstId: 70, instances: 4, name: 'Delay', groupCode: 'DLY', confidence: 'spec-v1.4' },
|
|
51
|
+
{ firstId: 74, instances: 4, name: 'Multitap Delay', groupCode: 'MTD', confidence: 'spec-v1.4' },
|
|
52
|
+
{ firstId: 78, instances: 4, name: 'Chorus', groupCode: 'CHO', confidence: 'spec-v1.4' },
|
|
53
|
+
{ firstId: 82, instances: 4, name: 'Flanger', groupCode: 'FLG', confidence: 'spec-v1.4' },
|
|
54
|
+
{ firstId: 86, instances: 4, name: 'Rotary', groupCode: 'ROT', confidence: 'spec-v1.4' },
|
|
55
|
+
{ firstId: 90, instances: 4, name: 'Phaser', groupCode: 'PHA', confidence: 'spec-v1.4' },
|
|
56
|
+
{ firstId: 94, instances: 4, name: 'Wah', groupCode: 'WAH', confidence: 'spec-v1.4' },
|
|
57
|
+
{ firstId: 98, instances: 4, name: 'Formant', groupCode: 'FRM', confidence: 'spec-v1.4' },
|
|
58
|
+
{ firstId: 102, instances: 4, name: 'Volume/Pan', groupCode: 'VOL', confidence: 'spec-v1.4' },
|
|
59
|
+
{ firstId: 106, instances: 4, name: 'Pan/Tremolo', groupCode: 'PTR', confidence: 'spec-v1.4' },
|
|
60
|
+
{ firstId: 110, instances: 4, name: 'Pitch', groupCode: 'PIT', confidence: 'spec-v1.4' },
|
|
61
|
+
{ firstId: 114, instances: 4, name: 'Filter', groupCode: 'FIL', confidence: 'spec-v1.4' },
|
|
62
|
+
{ firstId: 118, instances: 4, name: 'Fuzz', groupCode: 'FUZ', confidence: 'spec-v1.4' },
|
|
63
|
+
{ firstId: 122, instances: 4, name: 'Enhancer', groupCode: 'ENH', confidence: 'spec-v1.4' },
|
|
64
|
+
{ firstId: 126, instances: 4, name: 'Mixer', groupCode: 'MIX', confidence: 'spec-v1.4' },
|
|
65
|
+
{ firstId: 130, instances: 4, name: 'Synth', groupCode: 'SYN', confidence: 'spec-v1.4' },
|
|
66
|
+
{ firstId: 134, instances: 4, name: 'Vocoder', groupCode: 'VOC', availability: 'iii-only', confidence: 'spec-v1.4' },
|
|
67
|
+
{ firstId: 138, instances: 4, name: 'Megatap Delay', groupCode: 'MGD', confidence: 'spec-v1.4' },
|
|
68
|
+
{ firstId: 142, instances: 4, name: 'Crossover', groupCode: 'XOV', availability: 'iii+fm9', confidence: 'spec-v1.4' },
|
|
69
|
+
{ firstId: 146, instances: 4, name: 'Gate/Expander', groupCode: 'GAT', confidence: 'spec-v1.4' },
|
|
70
|
+
{ firstId: 150, instances: 4, name: 'Ring Modulator', groupCode: 'RNG', confidence: 'spec-v1.4' },
|
|
71
|
+
{ firstId: 154, instances: 4, name: 'Multiband Compressor', groupCode: 'MBC', confidence: 'spec-v1.4' },
|
|
72
|
+
{ firstId: 158, instances: 4, name: 'Ten-Tap Delay', groupCode: 'TTD', confidence: 'spec-v1.4' },
|
|
73
|
+
{ firstId: 162, instances: 4, name: 'Resonator', groupCode: 'RES', confidence: 'spec-v1.4' },
|
|
74
|
+
{ firstId: 166, instances: 4, name: 'Looper', groupCode: 'LPR', confidence: 'spec-v1.4' },
|
|
75
|
+
{ firstId: 170, instances: 4, name: 'Tone Match', groupCode: 'TMA', availability: 'iii-only', confidence: 'spec-v1.4' },
|
|
76
|
+
{ firstId: 174, instances: 4, name: 'Real-Time Analyzer', groupCode: 'RTA', availability: 'iii-only', confidence: 'spec-v1.4' },
|
|
77
|
+
{ firstId: 178, instances: 4, name: 'Plex Delay', groupCode: 'PLX', confidence: 'spec-v1.4' },
|
|
78
|
+
{ firstId: 182, instances: 4, name: 'Send', groupCode: 'SND', confidence: 'spec-v1.4' },
|
|
79
|
+
{ firstId: 186, instances: 4, name: 'Return', groupCode: 'RTN', confidence: 'spec-v1.4' },
|
|
80
|
+
{ firstId: 190, instances: 1, name: 'Scene MIDI', groupCode: 'SMI', confidence: 'spec-v1.4', addressable: false },
|
|
81
|
+
{ firstId: 191, instances: 4, name: 'Multiplexer', groupCode: 'MUX', confidence: 'spec-v1.4' },
|
|
82
|
+
{ firstId: 195, instances: 4, name: 'IR Player', groupCode: 'IRP', availability: 'iii-only', confidence: 'spec-v1.4' },
|
|
83
|
+
{ firstId: 199, instances: 1, name: 'Foot Controller', groupCode: 'FC', confidence: 'spec-v1.4', addressable: false },
|
|
84
|
+
{ firstId: 200, instances: 1, name: 'Preset FC', groupCode: 'PFC', confidence: 'spec-v1.4', addressable: false },
|
|
85
|
+
// ── Blocks NOT in v1.4 Appendix 1 ───────────────────────────────
|
|
86
|
+
// AMP is mysteriously absent from v1.4 — either in the 3..34
|
|
87
|
+
// reserved range or deliberately omitted from the 3rd-party MIDI
|
|
88
|
+
// surface. STATUS_DUMP against a preset containing AMP would
|
|
89
|
+
// decode the real ID.
|
|
90
|
+
{ firstId: null, instances: 4, name: 'Amp', groupCode: 'AMP', confidence: 'pending-capture' },
|
|
91
|
+
// Post-firmware-1.13 additions (PDF predates these by ~6 years)
|
|
92
|
+
{ firstId: null, instances: 4, name: 'Dynamic Distortion', groupCode: 'DYD', availability: 'iii-only', confidence: 'pending-capture' },
|
|
93
|
+
{ firstId: null, instances: 4, name: 'NAM', groupCode: 'NAM', availability: 'iii-only', confidence: 'pending-capture' },
|
|
94
|
+
// Editor-asset-only entries — UI surface exists, no SysEx ID confirmed
|
|
95
|
+
{ firstId: null, instances: 1, name: 'Global Block', groupCode: 'GBK', availability: 'iii-only', confidence: 'editor-asset' },
|
|
96
|
+
// Shunt is a grid-layout primitive (a pass-through cell); the III
|
|
97
|
+
// exposes it in the editor but the v1.4 PDF doesn't enumerate it.
|
|
98
|
+
{ firstId: null, instances: 1, name: 'Shunt', groupCode: 'SHT', confidence: 'editor-asset' },
|
|
99
|
+
];
|
|
100
|
+
// ── Lookups ────────────────────────────────────────────────────────
|
|
101
|
+
/** Lookup: lowercase block name → block descriptor. Case-insensitive. */
|
|
102
|
+
const NAMES_BY_LOWER = new Map(AXE_FX_III_BLOCKS.map((b) => [b.name.toLowerCase(), b]));
|
|
103
|
+
/** Lookup: groupCode → block descriptor. */
|
|
104
|
+
const BY_GROUP_CODE = new Map(AXE_FX_III_BLOCKS.map((b) => [b.groupCode, b]));
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a user-supplied block reference (display name or group code)
|
|
107
|
+
* to its block descriptor. Returns `undefined` if not found.
|
|
108
|
+
*/
|
|
109
|
+
export function resolveBlock(input) {
|
|
110
|
+
const trimmed = input.trim();
|
|
111
|
+
if (trimmed.length === 0)
|
|
112
|
+
return undefined;
|
|
113
|
+
return (NAMES_BY_LOWER.get(trimmed.toLowerCase()) ?? BY_GROUP_CODE.get(trimmed.toUpperCase()));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Resolve a "block + instance" reference (e.g. "Reverb 1", "Drive 2",
|
|
117
|
+
* "REV 3") to a concrete effect ID. Returns the effect ID, or throws
|
|
118
|
+
* with a helpful message if the block is unknown OR has no effect ID
|
|
119
|
+
* in the v1.4 spec (AMP, NAM, etc.).
|
|
120
|
+
*
|
|
121
|
+
* Accepts both:
|
|
122
|
+
* - `"Reverb 1"` (display name + instance number)
|
|
123
|
+
* - `"REV"` or `"Reverb"` (no instance → defaults to instance 1)
|
|
124
|
+
* - `{ block: 'Reverb', instance: 2 }` (object form, see overload)
|
|
125
|
+
*/
|
|
126
|
+
export function resolveEffectId(blockName, instance) {
|
|
127
|
+
// Try parsing trailing instance number out of the name itself.
|
|
128
|
+
const m = blockName.match(/^(.+?)\s*(\d+)?\s*$/);
|
|
129
|
+
const baseName = m?.[1]?.trim() ?? blockName;
|
|
130
|
+
const trailingNum = m?.[2] ? Number.parseInt(m[2], 10) : undefined;
|
|
131
|
+
const resolvedInstance = instance ?? trailingNum ?? 1;
|
|
132
|
+
const block = resolveBlock(baseName);
|
|
133
|
+
if (!block) {
|
|
134
|
+
throw new Error(`Unknown Axe-Fx III block "${blockName}". Try a name like "Reverb 1", ` +
|
|
135
|
+
'"Drive 2", or a 3-letter group code like "REV". Call ' +
|
|
136
|
+
'`axefx3_list_blocks` for the full catalog.');
|
|
137
|
+
}
|
|
138
|
+
if (block.firstId === null) {
|
|
139
|
+
throw new Error(`Axe-Fx III "${block.name}" has no effect ID in the v1.4 spec ` +
|
|
140
|
+
'(either reserved / unenumerated or added in firmware > 1.13). ' +
|
|
141
|
+
`${block.confidence === 'pending-capture' ? 'Run axefx3_status_dump against a preset that contains this block to decode its real effect ID.' : 'This block is shipping editor-only and may not be addressable via 3rd-party MIDI.'}`);
|
|
142
|
+
}
|
|
143
|
+
if (block.addressable === false) {
|
|
144
|
+
throw new Error(`Axe-Fx III "${block.name}" (effect ID ${block.firstId}) is listed in ` +
|
|
145
|
+
'v1.4 Appendix 1 but is NOT controllable via the 3rd-party MIDI ' +
|
|
146
|
+
"surface — it's an internal / FC-only block. set_bypass and " +
|
|
147
|
+
'set_channel will not affect it. ' +
|
|
148
|
+
'(Confirmed: ID_CONTROL=2, ID_MIDIBLOCK=190, ID_FOOTCONTROLLER=199, ' +
|
|
149
|
+
'ID_PRESET_FC=200.)');
|
|
150
|
+
}
|
|
151
|
+
if (resolvedInstance < 1 || resolvedInstance > block.instances) {
|
|
152
|
+
throw new Error(`Axe-Fx III ${block.name} instance ${resolvedInstance} out of range ` +
|
|
153
|
+
`(1..${block.instances}).`);
|
|
154
|
+
}
|
|
155
|
+
return block.firstId + (resolvedInstance - 1);
|
|
156
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axe-Fx III enum vocabulary overlay.
|
|
3
|
+
*
|
|
4
|
+
* The III params catalog (`params.ts`) tags each enum-typed parameter
|
|
5
|
+
* with `unit: 'enum'` but cannot ship a `enumValues: {0: 'OFF', ...}`
|
|
6
|
+
* table inline — III enum vocabularies are not in the public v1.4 spec
|
|
7
|
+
* and have not been mined from the Axe-Edit III binary's `.rdata`
|
|
8
|
+
* string pools yet (a substantial Ghidra workstream).
|
|
9
|
+
*
|
|
10
|
+
* This overlay fills the gap with three layers of evidence-tagged data:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Hardware-verified AM4 join**. Symbols whose stem matches an
|
|
13
|
+
* AM4 entry with a confirmed `enumValues` table are reused
|
|
14
|
+
* verbatim. Tag: `'am4-shared'`. Caveat: III firmware may extend
|
|
15
|
+
* these (e.g. adding amp models post-AM4); the AM4 vocabulary
|
|
16
|
+
* is the verified *subset*, not necessarily the complete list.
|
|
17
|
+
* 2. **Universal Fractal convention** (suffix-driven). Every
|
|
18
|
+
* Fractal device uses the same vocabulary for binary toggles
|
|
19
|
+
* (`_BYP`, `_MUTE`, `_ENABLE`), channel pickers (A/B/C/D),
|
|
20
|
+
* slope tables, and standard LFO waveforms. Tag: `'fractal-
|
|
21
|
+
* convention'`. Confidence: high — these vocabularies are
|
|
22
|
+
* stable across every Fractal product since the original
|
|
23
|
+
* Axe-Fx Standard (2006).
|
|
24
|
+
* 3. **III-specific direct entries**. Hand-curated for III-only
|
|
25
|
+
* params with values lifted from the v1.4 PDF (where it documents
|
|
26
|
+
* a vocabulary inline) or from the AxeEdit III XML when
|
|
27
|
+
* `<EditorControl type="dropdown*">` carries an inline value
|
|
28
|
+
* list. Tag: `'iii-spec'`.
|
|
29
|
+
*
|
|
30
|
+
* Consumers use `resolveEnumValues(paramName)` to look up the
|
|
31
|
+
* vocabulary; the function checks direct names first, then suffix
|
|
32
|
+
* conventions.
|
|
33
|
+
*
|
|
34
|
+
* **Hardware verification is the user's responsibility.** A wrong
|
|
35
|
+
* label in this overlay produces a misleading display but does NOT
|
|
36
|
+
* misroute wire bytes (the codec layer uses raw integer values). File
|
|
37
|
+
* a GitHub issue with a capture if your III shows a different label
|
|
38
|
+
* for a given wire value.
|
|
39
|
+
*/
|
|
40
|
+
/** Provenance tag for each overlay entry. */
|
|
41
|
+
export type EnumProvenance = 'am4-shared' | 'fractal-convention' | 'iii-spec';
|
|
42
|
+
/** Overlay entry — values map + provenance. */
|
|
43
|
+
export interface EnumOverlayEntry {
|
|
44
|
+
values: Readonly<Record<number, string>>;
|
|
45
|
+
provenance: EnumProvenance;
|
|
46
|
+
/** Optional note explaining the entry's limitations / sources. */
|
|
47
|
+
note?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Look up an enum vocabulary for an III parameter by its symbol name.
|
|
51
|
+
*
|
|
52
|
+
* resolveEnumValues('GLOBAL_TUNERMUTE')
|
|
53
|
+
* → { values: { 0: 'OFF', 1: 'ON' }, provenance: 'fractal-convention' }
|
|
54
|
+
*
|
|
55
|
+
* resolveEnumValues('REVERB_LFO1TYPE')
|
|
56
|
+
* → { values: { 0: 'Sine', ... }, provenance: 'am4-shared', note: ... }
|
|
57
|
+
*
|
|
58
|
+
* resolveEnumValues('NOT_A_REAL_PARAM')
|
|
59
|
+
* → undefined
|
|
60
|
+
*
|
|
61
|
+
* Lookup order: direct overrides first, then suffix rules in
|
|
62
|
+
* declaration order.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveEnumValues(name: string): EnumOverlayEntry | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Audit-friendly statistics for a calibration verifier or coverage
|
|
67
|
+
* report. Returns the number of entries in each tier.
|
|
68
|
+
*/
|
|
69
|
+
export declare function enumOverlayStats(): {
|
|
70
|
+
directOverrides: number;
|
|
71
|
+
suffixRules: number;
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=enumOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enumOverlay.d.ts","sourceRoot":"","sources":["../../src/axe-fx-iii/enumOverlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,oBAAoB,GAAG,UAAU,CAAC;AAE9E,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,UAAU,EAAE,cAAc,CAAC;IAC3B,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA4LD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAO5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB,CAKA"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axe-Fx III enum vocabulary overlay.
|
|
3
|
+
*
|
|
4
|
+
* The III params catalog (`params.ts`) tags each enum-typed parameter
|
|
5
|
+
* with `unit: 'enum'` but cannot ship a `enumValues: {0: 'OFF', ...}`
|
|
6
|
+
* table inline — III enum vocabularies are not in the public v1.4 spec
|
|
7
|
+
* and have not been mined from the Axe-Edit III binary's `.rdata`
|
|
8
|
+
* string pools yet (a substantial Ghidra workstream).
|
|
9
|
+
*
|
|
10
|
+
* This overlay fills the gap with three layers of evidence-tagged data:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Hardware-verified AM4 join**. Symbols whose stem matches an
|
|
13
|
+
* AM4 entry with a confirmed `enumValues` table are reused
|
|
14
|
+
* verbatim. Tag: `'am4-shared'`. Caveat: III firmware may extend
|
|
15
|
+
* these (e.g. adding amp models post-AM4); the AM4 vocabulary
|
|
16
|
+
* is the verified *subset*, not necessarily the complete list.
|
|
17
|
+
* 2. **Universal Fractal convention** (suffix-driven). Every
|
|
18
|
+
* Fractal device uses the same vocabulary for binary toggles
|
|
19
|
+
* (`_BYP`, `_MUTE`, `_ENABLE`), channel pickers (A/B/C/D),
|
|
20
|
+
* slope tables, and standard LFO waveforms. Tag: `'fractal-
|
|
21
|
+
* convention'`. Confidence: high — these vocabularies are
|
|
22
|
+
* stable across every Fractal product since the original
|
|
23
|
+
* Axe-Fx Standard (2006).
|
|
24
|
+
* 3. **III-specific direct entries**. Hand-curated for III-only
|
|
25
|
+
* params with values lifted from the v1.4 PDF (where it documents
|
|
26
|
+
* a vocabulary inline) or from the AxeEdit III XML when
|
|
27
|
+
* `<EditorControl type="dropdown*">` carries an inline value
|
|
28
|
+
* list. Tag: `'iii-spec'`.
|
|
29
|
+
*
|
|
30
|
+
* Consumers use `resolveEnumValues(paramName)` to look up the
|
|
31
|
+
* vocabulary; the function checks direct names first, then suffix
|
|
32
|
+
* conventions.
|
|
33
|
+
*
|
|
34
|
+
* **Hardware verification is the user's responsibility.** A wrong
|
|
35
|
+
* label in this overlay produces a misleading display but does NOT
|
|
36
|
+
* misroute wire bytes (the codec layer uses raw integer values). File
|
|
37
|
+
* a GitHub issue with a capture if your III shows a different label
|
|
38
|
+
* for a given wire value.
|
|
39
|
+
*/
|
|
40
|
+
// ── Universal Fractal vocabularies ───────────────────────────────
|
|
41
|
+
/** Binary OFF/ON toggle — every Fractal product uses this. */
|
|
42
|
+
const BINARY_OFF_ON = {
|
|
43
|
+
values: { 0: 'OFF', 1: 'ON' },
|
|
44
|
+
provenance: 'fractal-convention',
|
|
45
|
+
};
|
|
46
|
+
/** Bypassed/engaged toggle — bypass state. */
|
|
47
|
+
const BYPASS_STATE = {
|
|
48
|
+
values: { 0: 'ENGAGED', 1: 'BYPASSED' },
|
|
49
|
+
provenance: 'fractal-convention',
|
|
50
|
+
};
|
|
51
|
+
/** Channel A/B/C/D picker — block-channel selector. */
|
|
52
|
+
const CHANNEL_PICKER = {
|
|
53
|
+
values: { 0: 'A', 1: 'B', 2: 'C', 3: 'D' },
|
|
54
|
+
provenance: 'fractal-convention',
|
|
55
|
+
};
|
|
56
|
+
/** Slope table — filter slopes in dB/octave. */
|
|
57
|
+
const FILTER_SLOPE = {
|
|
58
|
+
values: { 0: '6 dB/OCT', 1: '12 dB/OCT', 2: '24 dB/OCT', 3: '36 dB/OCT' },
|
|
59
|
+
provenance: 'fractal-convention',
|
|
60
|
+
};
|
|
61
|
+
/** Reverb low/high cut slope — Normal/Steep (AM4-verified, shared with III). */
|
|
62
|
+
const REVERB_CUT_SLOPE = {
|
|
63
|
+
values: { 0: 'Normal', 1: 'Steep' },
|
|
64
|
+
provenance: 'am4-shared',
|
|
65
|
+
};
|
|
66
|
+
/** Input-select stereo picker (L+R / L / R). */
|
|
67
|
+
const INPUT_SELECT_3WAY = {
|
|
68
|
+
values: { 0: 'L+R', 1: 'LEFT', 2: 'RIGHT' },
|
|
69
|
+
provenance: 'fractal-convention',
|
|
70
|
+
};
|
|
71
|
+
/** Input-select stereo picker (LEFT / RIGHT / SUM L+R). */
|
|
72
|
+
const INPUT_SELECT_SUM = {
|
|
73
|
+
values: { 0: 'LEFT', 1: 'RIGHT', 2: 'SUM L+R' },
|
|
74
|
+
provenance: 'fractal-convention',
|
|
75
|
+
};
|
|
76
|
+
/** Mute/thru toggle. */
|
|
77
|
+
const MUTE_THRU = {
|
|
78
|
+
values: { 0: 'Thru', 1: 'Mute' },
|
|
79
|
+
provenance: 'fractal-convention',
|
|
80
|
+
};
|
|
81
|
+
/** Pre/Post/Mid/End/Pre-Mid block placement. */
|
|
82
|
+
const PRE_POST_MID = {
|
|
83
|
+
values: { 0: 'PRE', 1: 'POST', 2: 'MID', 3: 'END', 4: 'PRE-MID' },
|
|
84
|
+
provenance: 'fractal-convention',
|
|
85
|
+
};
|
|
86
|
+
/** Pan / NONE / RIGHT / LEFT / BOTH. */
|
|
87
|
+
const PAN_4WAY = {
|
|
88
|
+
values: { 0: 'NONE', 1: 'RIGHT', 2: 'LEFT', 3: 'BOTH' },
|
|
89
|
+
provenance: 'fractal-convention',
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Standard LFO waveform table — shared across every Fractal block that
|
|
93
|
+
* uses an LFO. Order is the AM4 / II / III canonical layout (verified
|
|
94
|
+
* against AM4 hardware Session 42; III uses the same ordering per
|
|
95
|
+
* AxeEdit III's XML `dropdownLFOType` control).
|
|
96
|
+
*/
|
|
97
|
+
const LFO_WAVEFORMS = {
|
|
98
|
+
values: {
|
|
99
|
+
0: 'Sine',
|
|
100
|
+
1: 'Triangle',
|
|
101
|
+
2: 'Square',
|
|
102
|
+
3: 'Saw Up',
|
|
103
|
+
4: 'Saw Down',
|
|
104
|
+
5: 'Random',
|
|
105
|
+
6: 'Smooth',
|
|
106
|
+
7: 'Log',
|
|
107
|
+
8: 'Exp',
|
|
108
|
+
9: 'Pulse',
|
|
109
|
+
},
|
|
110
|
+
provenance: 'am4-shared',
|
|
111
|
+
note: 'LFO_WAVEFORMS_VALUES from AM4; III preserves the ordering per AxeEdit III XML.',
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Tempo divisions — 79-entry table (0..78) shared across every Fractal
|
|
115
|
+
* tempo-sync widget. AM4-verified.
|
|
116
|
+
*/
|
|
117
|
+
const TEMPO_DIVISIONS_PARTIAL = {
|
|
118
|
+
values: {
|
|
119
|
+
0: 'None',
|
|
120
|
+
1: '4x Whole', 2: '2x Whole', 3: 'Whole', 4: 'Whole Triplet',
|
|
121
|
+
5: 'Half Dotted', 6: 'Half', 7: 'Half Triplet',
|
|
122
|
+
8: 'Quarter Dotted', 9: 'Quarter', 10: 'Quarter Triplet',
|
|
123
|
+
11: '8th Dotted', 12: '8th', 13: '8th Triplet',
|
|
124
|
+
14: '16th Dotted', 15: '16th', 16: '16th Triplet',
|
|
125
|
+
17: '32nd Dotted', 18: '32nd', 19: '32nd Triplet',
|
|
126
|
+
20: '64th Dotted', 21: '64th', 22: '64th Triplet',
|
|
127
|
+
},
|
|
128
|
+
provenance: 'am4-shared',
|
|
129
|
+
note: 'Top 23 entries from AM4 TEMPO_DIVISIONS_VALUES; full 79-entry table available via AM4 import.',
|
|
130
|
+
};
|
|
131
|
+
// ── Suffix → vocabulary map ─────────────────────────────────────
|
|
132
|
+
//
|
|
133
|
+
// Order matters: more-specific suffixes first, then catch-alls.
|
|
134
|
+
// Each tuple is [suffix, entry] — matched against the *end* of a
|
|
135
|
+
// param's `name` field. The first match wins.
|
|
136
|
+
const SUFFIX_RULES = [
|
|
137
|
+
// Most specific first.
|
|
138
|
+
['_LOWCUTSLOPE', REVERB_CUT_SLOPE],
|
|
139
|
+
['_HIGHCUTSLOPE', REVERB_CUT_SLOPE],
|
|
140
|
+
['_LOW_CUT_SLOPE', REVERB_CUT_SLOPE],
|
|
141
|
+
['_HIGH_CUT_SLOPE', REVERB_CUT_SLOPE],
|
|
142
|
+
['_LFO1TYPE', LFO_WAVEFORMS],
|
|
143
|
+
['_LFO2TYPE', LFO_WAVEFORMS],
|
|
144
|
+
['_LFO3TYPE', LFO_WAVEFORMS],
|
|
145
|
+
['_LFO4TYPE', LFO_WAVEFORMS],
|
|
146
|
+
['_LFO_1_TYPE', LFO_WAVEFORMS],
|
|
147
|
+
['_LFO_2_TYPE', LFO_WAVEFORMS],
|
|
148
|
+
['_LFO_3_TYPE', LFO_WAVEFORMS],
|
|
149
|
+
['_LFO_4_TYPE', LFO_WAVEFORMS],
|
|
150
|
+
['_LFO_TYPE', LFO_WAVEFORMS],
|
|
151
|
+
['_LFOTYPE', LFO_WAVEFORMS],
|
|
152
|
+
['_TEMPO', TEMPO_DIVISIONS_PARTIAL],
|
|
153
|
+
['_SLOPE', FILTER_SLOPE],
|
|
154
|
+
['_CHANNEL', CHANNEL_PICKER],
|
|
155
|
+
['_CHAN', CHANNEL_PICKER],
|
|
156
|
+
['_INPUT_SELECT', INPUT_SELECT_3WAY],
|
|
157
|
+
['_INPUTSELECT', INPUT_SELECT_3WAY],
|
|
158
|
+
['_INSEL', INPUT_SELECT_3WAY],
|
|
159
|
+
// Binary toggles — catch-all suffix tail. Apply last so more-specific
|
|
160
|
+
// suffixes win.
|
|
161
|
+
['_BYP', BYPASS_STATE],
|
|
162
|
+
['_BYPASS', BYPASS_STATE],
|
|
163
|
+
['_MUTE', MUTE_THRU],
|
|
164
|
+
['_MUTE1', MUTE_THRU],
|
|
165
|
+
['_MUTE2', MUTE_THRU],
|
|
166
|
+
['_MUTE3', MUTE_THRU],
|
|
167
|
+
['_MUTE4', MUTE_THRU],
|
|
168
|
+
['_ENABLE', BINARY_OFF_ON],
|
|
169
|
+
['_DISABLE', BINARY_OFF_ON],
|
|
170
|
+
['_AUTOON', BINARY_OFF_ON],
|
|
171
|
+
['_AUTOENABLE', BINARY_OFF_ON],
|
|
172
|
+
['_AUTO', BINARY_OFF_ON],
|
|
173
|
+
['_INVERT', BINARY_OFF_ON],
|
|
174
|
+
['_HOLD', BINARY_OFF_ON],
|
|
175
|
+
];
|
|
176
|
+
// ── Direct-name overrides ────────────────────────────────────────
|
|
177
|
+
//
|
|
178
|
+
// Hand-curated entries for III-specific params where a suffix rule
|
|
179
|
+
// would be wrong or where the vocabulary is non-standard.
|
|
180
|
+
const DIRECT_OVERRIDES = {
|
|
181
|
+
GLOBAL_CABINETBYP: BYPASS_STATE,
|
|
182
|
+
GLOBAL_PWRAMPBYP: BYPASS_STATE,
|
|
183
|
+
GLOBAL_TUNERMUTE: BINARY_OFF_ON,
|
|
184
|
+
GLOBAL_DELAYSPILL: BINARY_OFF_ON,
|
|
185
|
+
GLOBAL_USETUNEOFFSETS: BINARY_OFF_ON,
|
|
186
|
+
REVERB_HOLD: {
|
|
187
|
+
values: { 0: 'OFF', 1: 'STACK', 2: 'HOLD' },
|
|
188
|
+
provenance: 'am4-shared',
|
|
189
|
+
},
|
|
190
|
+
REVERB_NUMSPRINGS: {
|
|
191
|
+
values: { 0: '1', 1: '2', 2: '3' },
|
|
192
|
+
provenance: 'iii-spec',
|
|
193
|
+
note: 'Inferred from spring-reverb editor presentation; III-untested.',
|
|
194
|
+
},
|
|
195
|
+
PRESET_BAND: {
|
|
196
|
+
values: { 0: 'Low', 1: 'Mid', 2: 'High' },
|
|
197
|
+
provenance: 'iii-spec',
|
|
198
|
+
note: 'Multiband processor band-index — inferred from editor layout.',
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
// ── Public API ────────────────────────────────────────────────────
|
|
202
|
+
/**
|
|
203
|
+
* Look up an enum vocabulary for an III parameter by its symbol name.
|
|
204
|
+
*
|
|
205
|
+
* resolveEnumValues('GLOBAL_TUNERMUTE')
|
|
206
|
+
* → { values: { 0: 'OFF', 1: 'ON' }, provenance: 'fractal-convention' }
|
|
207
|
+
*
|
|
208
|
+
* resolveEnumValues('REVERB_LFO1TYPE')
|
|
209
|
+
* → { values: { 0: 'Sine', ... }, provenance: 'am4-shared', note: ... }
|
|
210
|
+
*
|
|
211
|
+
* resolveEnumValues('NOT_A_REAL_PARAM')
|
|
212
|
+
* → undefined
|
|
213
|
+
*
|
|
214
|
+
* Lookup order: direct overrides first, then suffix rules in
|
|
215
|
+
* declaration order.
|
|
216
|
+
*/
|
|
217
|
+
export function resolveEnumValues(name) {
|
|
218
|
+
const direct = DIRECT_OVERRIDES[name];
|
|
219
|
+
if (direct)
|
|
220
|
+
return direct;
|
|
221
|
+
for (const [suffix, entry] of SUFFIX_RULES) {
|
|
222
|
+
if (name.endsWith(suffix))
|
|
223
|
+
return entry;
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Audit-friendly statistics for a calibration verifier or coverage
|
|
229
|
+
* report. Returns the number of entries in each tier.
|
|
230
|
+
*/
|
|
231
|
+
export function enumOverlayStats() {
|
|
232
|
+
return {
|
|
233
|
+
directOverrides: Object.keys(DIRECT_OVERRIDES).length,
|
|
234
|
+
suffixRules: SUFFIX_RULES.length,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { AXE_FX_III_BLOCKS, resolveBlock, resolveEffectId, } from './blockTypes.js';
|
|
2
|
+
export type { AxeFxIIIBlock, ConfidenceTag } from './blockTypes.js';
|
|
3
|
+
export { PARAMS, PARAMS_BY_FAMILY, PARAM_BY_KEY, FAMILIES } from './params.js';
|
|
4
|
+
export type { Unit, Param } from './params.js';
|
|
5
|
+
export { resolveEnumValues, enumOverlayStats } from './enumOverlay.js';
|
|
6
|
+
export type { EnumOverlayEntry, EnumProvenance } from './enumOverlay.js';
|
|
7
|
+
export { AXE_FX_III_MODEL_ID, FN_SET_GET_BYPASS, FN_SET_GET_CHANNEL, FN_SET_GET_SCENE, FN_QUERY_PATCH_NAME, FN_QUERY_SCENE_NAME, FN_SET_GET_LOOPER, FN_TEMPO_TAP, FN_TUNER_ON_OFF, FN_STATUS_DUMP, FN_SET_GET_TEMPO, FN_MULTIPURPOSE_RESPONSE, FN_PARAMETER_SETGET, QUERY_SENTINEL, packValue16, unpackValue16, buildSetParameter, buildGetParameter, buildSetParameterBypass, isSetGetParameterResponse, parseSetGetParameterResponse, buildSetGridCell, buildSetPresetName, buildStorePreset, buildSwitchPresetPC, buildSetBypass, buildGetBypass, buildSetChannel, buildGetChannel, buildSetScene, buildGetScene, buildQueryPatchName, buildQuerySceneName, buildSetLooper, buildGetLooperState, buildTempoTap, buildSetTuner, buildStatusDump, buildSetTempo, buildGetTempo, isSetGetBypassResponse, isSetGetChannelResponse, isSetGetSceneResponse, isQueryPatchNameResponse, isQuerySceneNameResponse, isSetGetLooperResponse, isStatusDumpResponse, isSetGetTempoResponse, isMultipurposeResponse, parseBypassResponse, parseChannelResponse, parseSceneResponse, parseQueryPatchNameResponse, parseQuerySceneNameResponse, parseLooperStateResponse, parseTempoResponse, parseMultipurposeResponse, describeMultipurposeResultCode, parseStatusDumpResponse, parseStateBroadcast, } from './setParam.js';
|
|
8
|
+
export type { LooperAction, LooperState, StatusDumpEntry, AxeFxIIIParameterFrameKind, } from './setParam.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/axe-fx-iii/index.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAK/C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIzE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,yBAAyB,EACzB,8BAA8B,EAC9B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,0BAA0B,GAC3B,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Barrel for fractal-midi/axe-fx-iii.
|
|
2
|
+
//
|
|
3
|
+
// **Status: 🟡 community beta.** The III protocol layer is scaffolded
|
|
4
|
+
// from Fractal's published "Axe-Fx III MIDI for Third-Party Devices"
|
|
5
|
+
// v1.4 PDF and the AxeEdit III editor assets. Wire envelopes are
|
|
6
|
+
// byte-verified against 10 public captures (FC-12, gabbernutter
|
|
7
|
+
// forum); per-effect param-ID calibration is sparse (~11%) because
|
|
8
|
+
// Fractal deliberately omits per-block param IDs from the public
|
|
9
|
+
// spec. Use with that caveat.
|
|
10
|
+
// Data — block roster + flat param table (2017 params from AxeEdit
|
|
11
|
+
// III's `__block_layout.xml` mining).
|
|
12
|
+
export { AXE_FX_III_BLOCKS, resolveBlock, resolveEffectId, } from './blockTypes.js';
|
|
13
|
+
export { PARAMS, PARAMS_BY_FAMILY, PARAM_BY_KEY, FAMILIES } from './params.js';
|
|
14
|
+
// Enum vocabulary overlay — universal Fractal conventions + AM4-
|
|
15
|
+
// verified shared symbols + III-specific direct overrides. See
|
|
16
|
+
// `enumOverlay.ts` for evidence chain and provenance tagging.
|
|
17
|
+
export { resolveEnumValues, enumOverlayStats } from './enumOverlay.js';
|
|
18
|
+
// Codec — wire-byte builders + parsers. Function-code constants
|
|
19
|
+
// re-exported for callers building custom envelopes.
|
|
20
|
+
export { AXE_FX_III_MODEL_ID, FN_SET_GET_BYPASS, FN_SET_GET_CHANNEL, FN_SET_GET_SCENE, FN_QUERY_PATCH_NAME, FN_QUERY_SCENE_NAME, FN_SET_GET_LOOPER, FN_TEMPO_TAP, FN_TUNER_ON_OFF, FN_STATUS_DUMP, FN_SET_GET_TEMPO, FN_MULTIPURPOSE_RESPONSE, FN_PARAMETER_SETGET, QUERY_SENTINEL, packValue16, unpackValue16, buildSetParameter, buildGetParameter, buildSetParameterBypass, isSetGetParameterResponse, parseSetGetParameterResponse, buildSetGridCell, buildSetPresetName, buildStorePreset, buildSwitchPresetPC, buildSetBypass, buildGetBypass, buildSetChannel, buildGetChannel, buildSetScene, buildGetScene, buildQueryPatchName, buildQuerySceneName, buildSetLooper, buildGetLooperState, buildTempoTap, buildSetTuner, buildStatusDump, buildSetTempo, buildGetTempo, isSetGetBypassResponse, isSetGetChannelResponse, isSetGetSceneResponse, isQueryPatchNameResponse, isQuerySceneNameResponse, isSetGetLooperResponse, isStatusDumpResponse, isSetGetTempoResponse, isMultipurposeResponse, parseBypassResponse, parseChannelResponse, parseSceneResponse, parseQueryPatchNameResponse, parseQuerySceneNameResponse, parseLooperStateResponse, parseTempoResponse, parseMultipurposeResponse, describeMultipurposeResultCode, parseStatusDumpResponse, parseStateBroadcast, } from './setParam.js';
|