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,863 @@
|
|
|
1
|
+
// Universal per-block output Balance at cache id=2 — signature
|
|
2
|
+
// (a=-1, b=1, c=100) across every confirmed block. Blocks Guide §347
|
|
3
|
+
// documents Balance as a standard block-level parameter that pans
|
|
4
|
+
// the block's output between left and right. Requires the
|
|
5
|
+
// `bipolar_percent` unit (display -100..+100, internal -1..+1,
|
|
6
|
+
// scale 100) which generator default for c=100 would misclassify
|
|
7
|
+
// as plain `percent` (0..100).
|
|
8
|
+
const BALANCE = {
|
|
9
|
+
name: 'balance',
|
|
10
|
+
unit: 'bipolar_percent',
|
|
11
|
+
displayMin: -100,
|
|
12
|
+
displayMax: 100,
|
|
13
|
+
};
|
|
14
|
+
export const PARAM_NAMES = {
|
|
15
|
+
amp: {
|
|
16
|
+
2: BALANCE,
|
|
17
|
+
// Session 29 (HW-015): Out Boost Level — dB knob on the Extras tab,
|
|
18
|
+
// cache (a=0, b=4, c=1, step=0.05). Wire-verified at pidHigh=0x08.
|
|
19
|
+
8: { name: 'out_boost_level', unit: 'db', displayMin: 0, displayMax: 4 },
|
|
20
|
+
10: 'type',
|
|
21
|
+
11: 'gain',
|
|
22
|
+
12: 'bass',
|
|
23
|
+
// ids 13/14 (mid/treble) still structural — cache signature identical
|
|
24
|
+
// to gain/bass (knob_0_10, 0..1 range, step 0.001). Named per the
|
|
25
|
+
// AM4 Owner's Manual line 1563 tone-stack order "Gain, Bass, Mid,
|
|
26
|
+
// Treble, Presence, Level". HW-014 spot-check still pending.
|
|
27
|
+
13: 'mid',
|
|
28
|
+
14: 'treble',
|
|
29
|
+
// Session 29 (HW-015): id 15 (pidHigh=0x0f) was mis-inferred as
|
|
30
|
+
// 'presence' in Session 26 from the cache signature alone. Two
|
|
31
|
+
// wire captures (amp-master on an unknown Marshall-family amp +
|
|
32
|
+
// amp-master-2 on "Brit 800 #34") prove this register is Master.
|
|
33
|
+
// Real Presence was subsequently captured at id 30 (pidHigh=0x1e).
|
|
34
|
+
15: 'master',
|
|
35
|
+
// Session 29 (HW-015): Depth at pidHigh=0x1a, knob_0_10. Wire-
|
|
36
|
+
// verified with a full 0→10 sweep capture.
|
|
37
|
+
26: 'depth',
|
|
38
|
+
// Session 29 (HW-015): Presence at pidHigh=0x1e, knob_0_10. Wire-
|
|
39
|
+
// verified on the same amp as amp-master. Corrects the Session 26
|
|
40
|
+
// structural guess at id 15.
|
|
41
|
+
30: 'presence',
|
|
42
|
+
// HW-040 (Session 36, 2026-04-29): Amp Expert-Edit page from
|
|
43
|
+
// session-40-amp-expert.pcapng + paired AM4-Edit screenshot
|
|
44
|
+
// (FAS Modern III). Wiggle order + screenshot column order
|
|
45
|
+
// disambiguates the OFF/ON switches in the IDEAL column.
|
|
46
|
+
20: { name: 'bright_cap', unit: 'pf', displayMin: 10, displayMax: 10000 },
|
|
47
|
+
54: { name: 'input_trim', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
48
|
+
// amp's 8-band GEQ stores ±1 wire, scale ×12 → display ±12 dB.
|
|
49
|
+
// Cache ids 62..69 share the (a=-1, b=1, c=12) signature. Uses the
|
|
50
|
+
// `amp_geq_band` unit (scale 12) — distinct from drive's GEQ which
|
|
51
|
+
// stores ±12 wire directly (cache c=1) and uses plain `db`.
|
|
52
|
+
62: { name: 'geq_band_1', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
53
|
+
63: { name: 'geq_band_2', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
54
|
+
64: { name: 'geq_band_3', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
55
|
+
65: { name: 'geq_band_4', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
56
|
+
66: { name: 'geq_band_5', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
57
|
+
67: { name: 'geq_band_6', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
58
|
+
68: { name: 'geq_band_7', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
59
|
+
69: { name: 'geq_band_8', unit: 'amp_geq_band', displayMin: -12, displayMax: 12 },
|
|
60
|
+
77: { name: 'compressor_clarity', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
61
|
+
82: { name: 'compressor_amount', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
62
|
+
83: { name: 'compressor_threshold', unit: 'db', displayMin: -60, displayMax: 0 },
|
|
63
|
+
84: { name: 'master_vol_trim', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
64
|
+
104: { name: 'high_treble', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
65
|
+
// Session 89 (2026-05-16): DISTORT UI-MISSING closeout from
|
|
66
|
+
// samples/captured/decoded/am4-params-proposed.ts (Ghidra-mined
|
|
67
|
+
// catalog, Sessions 82–83) + cross-ref audit (35 UI-MISSING amp
|
|
68
|
+
// params at pidLow=0x003a). Same workflow as REVERB + DELAY
|
|
69
|
+
// commit 5de0870: route through paramNames.ts overrides to
|
|
70
|
+
// correct the cache pipeline's c=1 → 'db' fallback for Hz / count
|
|
71
|
+
// entries, plus full overrides where c is non-default (c=0.4166
|
|
72
|
+
// for spkr-reso knobs, c=2 for spkrdrive, c=31.62 for definition).
|
|
73
|
+
// Names re-state the GENERATED_PARAM_NAMES entry verbatim where
|
|
74
|
+
// present (firmware-truth from AM4-Edit.exe's variant resolver);
|
|
75
|
+
// only unit / displayMin / displayMax overrides are emitted to
|
|
76
|
+
// correct the cache pipeline defaults. Enum-typed ids (typecode
|
|
77
|
+
// 16) need custom value tables and stay hand-authored in
|
|
78
|
+
// params.ts later — see TODOs at the end of the amp: block.
|
|
79
|
+
//
|
|
80
|
+
// id=34 DISTORT_SPKRLFGAIN ("Low Reso") — cache type=48 a=0
|
|
81
|
+
// b=24 c=0.4166666… → display ×c → 0..10 knob. Generator can't
|
|
82
|
+
// infer c=0.4166; full override required. No GENERATED entry
|
|
83
|
+
// (resolver doesn't reach this id), so emit the name here too.
|
|
84
|
+
34: { name: 'low_reso', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
85
|
+
// id=38 DISTORT_MVCAP ("Master Vol Cap") — cache type=72 (log10)
|
|
86
|
+
// a=1e-6 b=1e-3 c=1e6 → 1..1000 pF (Master-Volume bypass
|
|
87
|
+
// capacitor in pF; sibling to amp.bright_cap at id=20 which uses
|
|
88
|
+
// the same pf unit). GENERATED has `master_vol_cap`.
|
|
89
|
+
38: { name: 'master_vol_cap', unit: 'pf', displayMin: 1, displayMax: 1000 },
|
|
90
|
+
// id=51 DISTORT_SPKRHFGAIN ("Hi Reso") — same shape as id=34
|
|
91
|
+
// (cache type=48, c=0.4166666…). GENERATED has `hi_reso`.
|
|
92
|
+
51: { name: 'hi_reso', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
93
|
+
// id=57 DISTORT_SPKRDRIVE ("Drive") — speaker-stage drive knob.
|
|
94
|
+
// Cache type=48 a=0 b=5 c=2 → display 0..10 knob. Generator can't
|
|
95
|
+
// infer c=2; full override required. GENERATED has `drive`, which
|
|
96
|
+
// collides with the existing drive block's `drive` (different
|
|
97
|
+
// block — no collision at lookup). Renamed to `spkr_drive` to
|
|
98
|
+
// avoid amp.drive vs drive.drive ambiguity in tool descriptions.
|
|
99
|
+
57: { name: 'spkr_drive', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
100
|
+
// id=79 DISTORT_INEQFREQ ("Frequency") — input-EQ peaking
|
|
101
|
+
// frequency. Cache type=66 a=100 b=10000 c=1 → Hz; default 'db'
|
|
102
|
+
// wrong. GENERATED has `frequency`. The label "Frequency" alone
|
|
103
|
+
// is ambiguous across amp's two EQ stages — renamed to
|
|
104
|
+
// `input_eq_frequency` to mirror the existing `input_eq_low_cut`
|
|
105
|
+
// / `input_eq_q` / `input_eq_gain` naming at adjacent paramIds.
|
|
106
|
+
79: { name: 'input_eq_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
107
|
+
// id=81 DISTORT_DRIVE2 ("Normal Gain") — second drive register
|
|
108
|
+
// for amps with a Normal channel (Marshall JTM/JCM-style).
|
|
109
|
+
// Cache type=48 c=10 → knob_0_10 inference works; unit not
|
|
110
|
+
// overridden. GENERATED has `overdrive` from the variant
|
|
111
|
+
// resolver — keep the resolver name. (Cache pipeline will
|
|
112
|
+
// auto-emit this entry on next gen-params since GENERATED
|
|
113
|
+
// supplies the name.) Registered here for documentation and
|
|
114
|
+
// to give the entry an explicit displayMin/Max audit trail.
|
|
115
|
+
81: { name: 'overdrive', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
116
|
+
// id=86 DISTORT_DEFINITION ("Definition") — Power-amp definition
|
|
117
|
+
// knob. Cache type=48 a=-0.31623 b=0.31623 c=31.62299 → bipolar
|
|
118
|
+
// ×c → -10..+10. The 31.62 scale is ≈ 10/√10 — power-amp
|
|
119
|
+
// definition appears stored on a log-axis but displayed as a
|
|
120
|
+
// bipolar knob. Generator can't infer c=31.62; full override.
|
|
121
|
+
// Use `count` (not bipolar_percent) since the front-panel reads
|
|
122
|
+
// -10.0..+10.0, not ±100%.
|
|
123
|
+
86: { name: 'definition', unit: 'count', displayMin: -10, displayMax: 10 },
|
|
124
|
+
// id=87 DISTORT_CFTHRESH ("Compression") — Cathode-Follower
|
|
125
|
+
// compression amount. Cache type=53 c=100 → percent inference
|
|
126
|
+
// works; unit not overridden. GENERATED has `compression`.
|
|
127
|
+
87: { name: 'compression', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
128
|
+
// id=90 DISTORT_HICUT ("High Cut") — Preamp high-cut Hz.
|
|
129
|
+
// Cache type=66 a=200 b=20000 c=1 → Hz; default 'db' wrong.
|
|
130
|
+
// GENERATED has `high_cut`.
|
|
131
|
+
90: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
132
|
+
// id=100 DISTORT_CBRATIO ("Cathode Resistance") — Cathode-bias
|
|
133
|
+
// resistance amount. Cache type=53 c=100 → percent inference
|
|
134
|
+
// works; unit not overridden. GENERATED has `cathode_resistance`.
|
|
135
|
+
100: { name: 'cathode_resistance', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
136
|
+
// id=125 DISTORT_VCCMON ("B+") — Power-supply B+ voltage MONITOR
|
|
137
|
+
// (read-only meter, not a knob). Cache type=0 a=0 b=1 c=1 → raw
|
|
138
|
+
// 0..1 float. Display as `count` (0..1) instead of the dB default.
|
|
139
|
+
// GENERATED has `vccmon` (resolver had no XML label). Renamed
|
|
140
|
+
// to `b_plus_monitor` to surface the function (it's the B+
|
|
141
|
+
// headroom indicator behind the "B+" front-panel display).
|
|
142
|
+
125: { name: 'b_plus_monitor', unit: 'count', displayMin: 0, displayMax: 1 },
|
|
143
|
+
// id=126 DISTORT_GAINMON ("Gain") — Drive-stage gain MONITOR
|
|
144
|
+
// (read-only meter). Cache type=0 c=1 → count. GENERATED has
|
|
145
|
+
// `gain_gainmon` (dedupe artifact since `gain` is owned by id=11).
|
|
146
|
+
// Renamed to `gain_monitor` for clarity.
|
|
147
|
+
126: { name: 'gain_monitor', unit: 'count', displayMin: 0, displayMax: 1 },
|
|
148
|
+
// id=137 DISTORT_VPLATEMON ("HEADROOM") — Power-amp plate-
|
|
149
|
+
// voltage headroom monitor. Cache type=0 c=1 → count.
|
|
150
|
+
// GENERATED has `headroom`.
|
|
151
|
+
137: { name: 'headroom_monitor', unit: 'count', displayMin: 0, displayMax: 1 },
|
|
152
|
+
// id=138 DISTORT_PREPRESENCE ("Treble") — Preamp-stage presence
|
|
153
|
+
// shaper (the label is "Treble" on some amps, but the wire/
|
|
154
|
+
// catalog calls it PREPRESENCE — pre-power-amp presence).
|
|
155
|
+
// Cache type=48 c=10 → knob_0_10 inference works. GENERATED has
|
|
156
|
+
// `presence_prepresence` (dedupe vs amp.presence at id=30).
|
|
157
|
+
138: { name: 'presence_prepresence', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
158
|
+
// id=140 DISTORT_PAHICUT ("Tone") — Power-amp high-cut shaper
|
|
159
|
+
// (label is "Tone" on AM4-Edit, catalog calls it PAHICUT).
|
|
160
|
+
// Cache type=48 c=10 → knob_0_10 inference works. GENERATED has
|
|
161
|
+
// `high_cut_pahicut`. Renamed to `pa_high_cut` for the same
|
|
162
|
+
// reason `high_cut` (id=90) is preamp-side: clearer family
|
|
163
|
+
// separation in describe_device output.
|
|
164
|
+
140: { name: 'pa_high_cut', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
165
|
+
// id=145 DISTORT_GLOBALMASTER ("Overdrive Volume") — Global
|
|
166
|
+
// post-amp master that scales after the cab sim. Cache type=48
|
|
167
|
+
// c=10 → knob_0_10 inference works. GENERATED has
|
|
168
|
+
// `overdrive_volume`.
|
|
169
|
+
145: { name: 'overdrive_volume', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
170
|
+
// TODOs — enum-typed ids (cache typecode=16). Each needs a custom
|
|
171
|
+
// enum value table hand-authored in params.ts; auto-emission via
|
|
172
|
+
// paramNames.ts would force the wrong enumImport (AMP_TYPES_VALUES
|
|
173
|
+
// is the Type enum at id=10, not these per-feature enums). The
|
|
174
|
+
// GENERATED_PARAM_NAMES table also skips these because the
|
|
175
|
+
// resolver only emits to non-enum cache slots. Symbol + range +
|
|
176
|
+
// value labels listed below for the future capture-driven pass:
|
|
177
|
+
// id=47 DISTORT_BOOST enum 0..1 "In Boost Sw" [OFF, ON]
|
|
178
|
+
// id=61 DISTORT_SATSWITCH enum 0..2 "Saturation Sw" [OFF, ON, ON (IDEAL)]
|
|
179
|
+
// id=76 DISTORT_PRETUBETYPE enum 0..8 "Preamp Tube Type" [12AX7A SYL, ECC83, 7025, 12AX7A JJ, ECC803S, EF86, 12AX7A RCA, 12AX7A, 12AX7B]
|
|
180
|
+
// id=93 DISTORT_SUPPLYTYPE enum 0..1 "Power Type" [AC, DC]
|
|
181
|
+
// id=103 DISTORT_PRESAG enum 0..1 "Preamp Sag" [OFF, ON]
|
|
182
|
+
// id=109 DISTORT_INEQTYPE enum 0..3 "Type" [LOWSHELF, PEAKING, HIGHSHELF, TILT EQ]
|
|
183
|
+
// id=111 DISTORT_PRESSHIFT enum 0..1 "Pres. Shift" [OFF, ON]
|
|
184
|
+
// id=117 DISTORT_EQPOSITION enum 0..2 "Location" [OUTPUT, PRE P.A., INPUT]
|
|
185
|
+
// id=130 DISTORT_BOOSTTYPE enum 0..14 "In Boost Type" [NEUTRAL, T808, T808 MOD, SUPER OD, FULL OD, AC BOOST, SHIMMER, FAS BOOST, GRINDER, TREBLE BOOST, MID BOOST, CC BOOST, SHRED BOOST, RCB BOOST, JP IIC+ SHRED]
|
|
186
|
+
// id=133 DISTORT_EQONOFF enum 0..1 "Off / On" [OFF, ON]
|
|
187
|
+
// id=135 DISTORT_SPKRMODEL enum 0..92 "Spkr Imp. Curve" — 93-cab impedance-curve table (factory speaker IRs). Big table; consider a dedicated SPKR_IMP_CURVE_VALUES export in cacheEnums.ts.
|
|
188
|
+
// id=141 DISTORT_PAONOFF enum 0..1 "Power Amp Modeling" [OFF, ON]
|
|
189
|
+
// id=142 DISTORT_SPKRBREAKUP enum 0..2 "Breakup" [SOFT, MEDIUM, HARD]
|
|
190
|
+
// id=144 DISTORT_PLATEDIODE enum 0..1 "Plate Suppr. Diodes" [OFF, ON]
|
|
191
|
+
// id=146 DISTORT_AUTO_SPKR_Z enum 0..1 "DynaMatch" [OFF, ON]
|
|
192
|
+
// id=147 DISTORT_NFBCOMP enum 0..1 "NFB Compensation" [OFF, ON]
|
|
193
|
+
// id=148 DISTORT_MODE_1 enum 0..3 "Mid/Gain Boost" [mode 1, mode 2, mode 3, mode 4]
|
|
194
|
+
// id=149 DISTORT_MODE_2 enum 0..3 "Tubes" — cache lists kind=float typecode=16 a=0 b=3; treat as 4-state enum (values pending capture).
|
|
195
|
+
//
|
|
196
|
+
// TODO — action / button-class (no cache record):
|
|
197
|
+
// id=65520 DISTORT_ZEROEQ button "Zero All" — XML exposes
|
|
198
|
+
// this as a UI control but cache has no record (button class,
|
|
199
|
+
// not a stored param). Wire-write should send the action to the
|
|
200
|
+
// GEQ block to reset all bands to 0 dB. Likely needs a synthetic
|
|
201
|
+
// entry in params.ts with a fixed action payload rather than a
|
|
202
|
+
// value range. Defer pending capture-confirmed wire shape.
|
|
203
|
+
},
|
|
204
|
+
drive: {
|
|
205
|
+
2: BALANCE,
|
|
206
|
+
10: 'type',
|
|
207
|
+
11: 'drive',
|
|
208
|
+
// AM4 Owner's Manual line 1330: "Page Right and dial in Drive, Tone,
|
|
209
|
+
// and Level." Cache records at 0x0C and 0x0D have the identical
|
|
210
|
+
// knob_0_10 signature to drive.drive (0x0B); typical pedal-UI order
|
|
211
|
+
// matches. `mix` at 0x0E follows the universal Mix Page pattern
|
|
212
|
+
// (percent). All three await Session D hardware spot-check.
|
|
213
|
+
12: 'tone',
|
|
214
|
+
13: 'level',
|
|
215
|
+
14: 'mix',
|
|
216
|
+
// HW-019 (Session 30, 2026-04-25): EQ-page knobs decoded from
|
|
217
|
+
// session-30-drive-basic-blackglass-7k. Cache ids 16/17 are the
|
|
218
|
+
// Hz cuts (raw passthrough — c=1 default would mis-classify as dB),
|
|
219
|
+
// ids 20/21/23 are the knob_0_10 Bass/Mid/Treble flanking id 22
|
|
220
|
+
// (mid frequency in Hz). T808 OD doesn't expose these — the
|
|
221
|
+
// session-30-drive-basic-t808-od capture only had drive/tone/level.
|
|
222
|
+
16: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
223
|
+
20: 'bass',
|
|
224
|
+
21: 'mid',
|
|
225
|
+
22: { name: 'mid_freq', unit: 'hz', displayMin: 200, displayMax: 2000 },
|
|
226
|
+
23: 'treble',
|
|
227
|
+
// HW-029 + HW-039 (Session 35, 2026-04-29): Blackglass 7K Drive
|
|
228
|
+
// Expert-Edit page exposes a second-Hz cut + a 10-band post-Drive
|
|
229
|
+
// Graphic EQ + DIGITAL LO-FI + ADVANCED knobs. Decoded from
|
|
230
|
+
// session-31-drive-expert.pcapng + paired AM4-Edit screenshot.
|
|
231
|
+
// Closes HW-029 (0x002d = high_mid knob, knob_0_10 — wiggled
|
|
232
|
+
// adjacent to drive.mid_freq + drive.treble in the timeline).
|
|
233
|
+
//
|
|
234
|
+
// - id 17 (0x0011): high_cut sibling to id 16. Cache c=1 a=200
|
|
235
|
+
// b=20000 — needs the 'hz' override (default would be dB).
|
|
236
|
+
// - id 24 (0x0018): Bit Reduce count, cache a=0 b=24 c=1 raw.
|
|
237
|
+
// Uses the 'count' unit (default for c=1 would be dB).
|
|
238
|
+
// - id 45 (0x002d): drive.high_mid for Blackglass 7K (cache c=10
|
|
239
|
+
// knob_0_10). Type-specific UI label varies; the register name
|
|
240
|
+
// reflects the most common Blackglass usage.
|
|
241
|
+
17: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
242
|
+
24: { name: 'bit_reduce', unit: 'count', displayMin: 0, displayMax: 24 },
|
|
243
|
+
// 10-band post-Drive Graphic EQ — cache ids 29..38 all share the
|
|
244
|
+
// bipolar dB ±12 signature (a=-12 b=12 c=1 step=0.025). Frequencies
|
|
245
|
+
// per the screenshot: 100, 160, 250, 400, 640, 1000, 1600, 2500,
|
|
246
|
+
// 4000, 6400 Hz. Wire-display match is byte-exact on all 10 bands
|
|
247
|
+
// (capture vs screenshot agree exactly).
|
|
248
|
+
29: { name: 'geq_band_1', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
249
|
+
30: { name: 'geq_band_2', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
250
|
+
31: { name: 'geq_band_3', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
251
|
+
32: { name: 'geq_band_4', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
252
|
+
33: { name: 'geq_band_5', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
253
|
+
34: { name: 'geq_band_6', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
254
|
+
35: { name: 'geq_band_7', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
255
|
+
36: { name: 'geq_band_8', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
256
|
+
37: { name: 'geq_band_9', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
257
|
+
38: { name: 'geq_band_10', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
258
|
+
45: 'high_mid',
|
|
259
|
+
},
|
|
260
|
+
reverb: {
|
|
261
|
+
1: 'mix',
|
|
262
|
+
2: BALANCE,
|
|
263
|
+
10: 'type',
|
|
264
|
+
// Blocks Guide §Reverb Basic Page: "Time — Sets the decay time."
|
|
265
|
+
// Cache 0x0B is 0.1..100 seconds, c=1 (raw passthrough). Needs the
|
|
266
|
+
// 'seconds' unit override — generator default for c=1 is 'db'.
|
|
267
|
+
// displayMin rounded to 0.1 (cache stores 0.10000000149…).
|
|
268
|
+
11: { name: 'time', unit: 'seconds', displayMin: 0.1 },
|
|
269
|
+
// Session 29 (HW-015): Size at pidHigh=0x0f, percent. Wire-verified
|
|
270
|
+
// on two captures — "Plate Size" (on Plate reverb type) and "Size"
|
|
271
|
+
// (on Room reverb type) both wrote to this register, confirming
|
|
272
|
+
// it's a universal reverb-size knob whose UI label depends on the
|
|
273
|
+
// active reverb type.
|
|
274
|
+
15: 'size',
|
|
275
|
+
// BK-033 (HW-025 #1, Session 30): the cache record at id=16 (0x10)
|
|
276
|
+
// signature LOOKED like predelay (0..0.25s × 1000 = 0..250 ms) but
|
|
277
|
+
// wire-testing proved it's a dead address — writes ack but the
|
|
278
|
+
// firmware ignores them. The real predelay register is id=19 (0x13);
|
|
279
|
+
// AM4-Edit captures wrote there for "Pre-Delay → 85 ms / 111.4 ms".
|
|
280
|
+
// Skipping id=16 here so the generator doesn't emit the wrong cache
|
|
281
|
+
// mapping; the corrected entry lives hand-authored in params.ts.
|
|
282
|
+
// The cache record at 0x13 has no name slot here either — it's
|
|
283
|
+
// not exposed via the auto-gen path; instead reverb.predelay is
|
|
284
|
+
// a pure KNOWN_PARAMS hand-authored entry going forward.
|
|
285
|
+
// Session 29 (HW-015): Spring-reverb-specific. Number of Springs
|
|
286
|
+
// (integer count 2..6) at pidHigh=0x1b; cache c=1 structurally
|
|
287
|
+
// ambiguous — needs 'count' override. Spring Tone (knob_0_10) at
|
|
288
|
+
// pidHigh=0x1c; cache signature matches knob_0_10 default. Both
|
|
289
|
+
// only visible in AM4-Edit when a Spring reverb type is active,
|
|
290
|
+
// but the registers remain writable on any type — writes simply
|
|
291
|
+
// no-op on non-spring reverbs.
|
|
292
|
+
27: { name: 'springs', unit: 'count', displayMin: 2, displayMax: 6 },
|
|
293
|
+
28: 'spring_tone',
|
|
294
|
+
// Session 29 follow-up (2026-04-21): Shimmer Verb / Plex Verb
|
|
295
|
+
// "Shift 1" and "Shift 2" pitch-shifter voices. Blocks Guide
|
|
296
|
+
// §Shimmer Verb Parameters: "Shift 1–8 — Sets the amount of
|
|
297
|
+
// detune within a range of ±24 semitones. This is where
|
|
298
|
+
// 'Shimmer' is born." AM4's reverb has two such voices (ids
|
|
299
|
+
// 56/57); the AxeFx/FM8-voice variant ships more. Cache signature
|
|
300
|
+
// (a=-24, b=24, c=1, step=1) matches the BG documentation
|
|
301
|
+
// exactly — needs the 'semitones' unit override since c=1 is
|
|
302
|
+
// structurally ambiguous. Structural registration; HW-014-style
|
|
303
|
+
// spot-check still required.
|
|
304
|
+
56: { name: 'shift_1', unit: 'semitones', displayMin: -24, displayMax: 24 },
|
|
305
|
+
57: { name: 'shift_2', unit: 'semitones', displayMin: -24, displayMax: 24 },
|
|
306
|
+
// Session 88 (2026-05-16): REVERB params from
|
|
307
|
+
// samples/captured/decoded/am4-params-proposed.ts (Ghidra-mined
|
|
308
|
+
// catalog, Session 82–83). Routed through paramNames.ts overrides
|
|
309
|
+
// (not direct cacheParams hand-edit) per the Session 84 unit-fallback
|
|
310
|
+
// trap — the cache pipeline's c=1 default emits `unit: 'db'`, wrong
|
|
311
|
+
// for Hz / Q / count / semitones / seconds. Names defer to the
|
|
312
|
+
// resolver-derived GENERATED_PARAM_NAMES entries (firmware-truth from
|
|
313
|
+
// AM4-Edit.exe's variant resolver) where they exist; only unit /
|
|
314
|
+
// displayMin / displayMax overrides are emitted to correct the
|
|
315
|
+
// cache pipeline defaults. Eight ids (51, 53, 54, 59, 61, 64, 68,
|
|
316
|
+
// 70) have no GENERATED entry — those that are enums need a custom
|
|
317
|
+
// value list and stay hand-authored in params.ts (see TODOs below).
|
|
318
|
+
//
|
|
319
|
+
// id=13 REVERB_HFRATIO ("High Decay") — cache type=64 log10
|
|
320
|
+
// a=0.01 b=1 → decay-ratio knob, NOT dB. Display 0.01..1 as a
|
|
321
|
+
// count (effectively a percent ×100, but cache emits as raw float).
|
|
322
|
+
13: { name: 'high_decay', unit: 'count', displayMin: 0.01, displayMax: 1 },
|
|
323
|
+
// id=22 REVERB_RATE — cache type=66 log10 a=0.01 b=1 → modulation
|
|
324
|
+
// rate. Range 0..1 is a normalized rate knob (UI shows 0.0..1.00 Hz
|
|
325
|
+
// approximately). Use 'hz' with the raw range.
|
|
326
|
+
22: { name: 'rate', unit: 'hz', displayMin: 0.01, displayMax: 1 },
|
|
327
|
+
// ids 30/31 REVERB_FREQ1/FREQ2 — cache type=66 log10 c=1, a/b are
|
|
328
|
+
// the actual Hz range. Default 'db' is wrong.
|
|
329
|
+
30: { name: 'frequency_1', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
330
|
+
31: { name: 'frequency_2', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
331
|
+
// ids 32/33 REVERB_Q1/Q2 — cache type=64 log10 a=0.1 b=10 → Q
|
|
332
|
+
// factor 0.1..10. Default 'db' is wrong; use 'count'.
|
|
333
|
+
32: { name: 'q_1', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
334
|
+
33: { name: 'q_2', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
335
|
+
// id=37 REVERB_LFTIME ("Low Decay") — cache type=64 log10 a=0.02
|
|
336
|
+
// b=2 sec → seconds, not dB.
|
|
337
|
+
37: { name: 'low_decay', unit: 'seconds', displayMin: 0.02, displayMax: 2 },
|
|
338
|
+
// id=38 REVERB_LFXOVER ("Xover Frequency") — cache type=66 a=100
|
|
339
|
+
// b=10000 → Hz.
|
|
340
|
+
38: { name: 'xover_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
341
|
+
// id=45 REVERB_EARLYDECAY ("Early Decay") — cache c=50 a=0 b=2 →
|
|
342
|
+
// display 0..100% (a*c..b*c). Generator can't infer c=50; full
|
|
343
|
+
// override required.
|
|
344
|
+
45: { name: 'early_decay', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
345
|
+
// id=49 REVERB_BASETYPE — cache kind=float type=16 range 0..8 →
|
|
346
|
+
// integer count selector (which base reverb algorithm). Should
|
|
347
|
+
// ideally be an enum with named base types, but cache lacks the
|
|
348
|
+
// value table — registered as count for now.
|
|
349
|
+
49: { name: 'basetype', unit: 'count', displayMin: 0, displayMax: 8 },
|
|
350
|
+
// id=50 REVERB_LFOPHASE — cache type=54 c=57.29578 (rad→deg) →
|
|
351
|
+
// 0..180 degrees per radians-encoded LFO phase convention.
|
|
352
|
+
50: { name: 'lfo_phase', unit: 'degrees', displayMin: 0, displayMax: 180 },
|
|
353
|
+
// id=55 REVERB_PITCHMIX — c=100 already correct percent; no
|
|
354
|
+
// override needed. Skipping.
|
|
355
|
+
// id=60 REVERB_PITCHTIME ("Splice Time") — cache type=52 c=1000
|
|
356
|
+
// a=0.01 b=2 sec → 10..2000 ms. Generator emits 'ms' but
|
|
357
|
+
// displayMin defaults to 0; override the lower bound.
|
|
358
|
+
60: { name: 'splice_time', unit: 'ms', displayMin: 10, displayMax: 2000 },
|
|
359
|
+
// id=63 REVERB_PITCHBAL ("Voice Balance") — c=100 a=-1 b=1 →
|
|
360
|
+
// bipolar_percent; generator default for c=100 is plain percent.
|
|
361
|
+
63: { name: 'voice_balance', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
362
|
+
// id=67 REVERB_PITCHLPF ("Pitch High Cut") — cache type=66 a=200
|
|
363
|
+
// b=20000 → Hz; default 'db' wrong.
|
|
364
|
+
67: { name: 'pitch_high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
365
|
+
// ids 71/72 REVERB_LOWQ/HIGHQ ("Low Cut Q" / "High Cut Q") —
|
|
366
|
+
// cache type=64 log10 a=0.1 b=10 → Q factor count; default 'db'
|
|
367
|
+
// wrong.
|
|
368
|
+
71: { name: 'low_cut_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
369
|
+
72: { name: 'high_cut_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
370
|
+
// TODO (no GENERATED entry, enum without value table — hand-author
|
|
371
|
+
// in params.ts with proper enum map):
|
|
372
|
+
// id=51 REVERB_INPUTSELECT enum 0..2 (likely L+R / L / R)
|
|
373
|
+
// id=53 REVERB_LOWSLOPE enum 0..1 (slope toggle)
|
|
374
|
+
// id=54 REVERB_HIGHSLOPE enum 0..1 (slope toggle)
|
|
375
|
+
// id=59 REVERB_PITCHDIR enum 0..3 (pitch shift direction)
|
|
376
|
+
// id=61 REVERB_PITCHPOS enum 0..2 (pitch position)
|
|
377
|
+
// id=64 REVERB_PREDLYTEMPO enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
378
|
+
// id=68 REVERB_SPRINGTYPE enum 0..1 (spring type toggle)
|
|
379
|
+
// id=70 REVERB_PREDLYTAP enum 0..1 (predelay tap mode)
|
|
380
|
+
},
|
|
381
|
+
delay: {
|
|
382
|
+
// Mix follows the universal percent-at-0x01 pattern (Blocks Guide
|
|
383
|
+
// §Common Mix/Level Parameters, p. 7). "delay block uses a
|
|
384
|
+
// different Mix Law compared to other blocks" — same param, just
|
|
385
|
+
// different internal curve; still the wet/dry knob.
|
|
386
|
+
1: 'mix',
|
|
387
|
+
2: BALANCE,
|
|
388
|
+
10: 'type',
|
|
389
|
+
12: 'time',
|
|
390
|
+
// Session 29 (HW-015): Feedback at pidHigh=0x0e. Cache (a=-1, b=1,
|
|
391
|
+
// c=100) is bipolar — negative feedback inverts the phase of the
|
|
392
|
+
// repeats, a standard Fractal delay feature.
|
|
393
|
+
14: { name: 'feedback', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
394
|
+
// HW-020 (Session 30, 2026-04-25): Ducking attenuation amount,
|
|
395
|
+
// session-30-delay-basic-digital-mono capture. Cache id=46 a=0
|
|
396
|
+
// b=80 c=1 → raw dB 0..80. Same signature as reverb.ducking
|
|
397
|
+
// (HW-018). delay.level (out-of-band, pidHigh=0x0000) and
|
|
398
|
+
// delay.stack_hold (per-block non-Type enum, pidHigh=0x001f) are
|
|
399
|
+
// hand-authored in params.ts directly.
|
|
400
|
+
46: 'ducking',
|
|
401
|
+
// HW-040 (Session 36, 2026-04-29): Delay Expert-Edit page on
|
|
402
|
+
// Ambient Stereo from session-40-delay-expert.pcapng. ~32 new
|
|
403
|
+
// params across BASIC + DIFFUSOR + EQ + MIX + DUCKER + COMPANDER
|
|
404
|
+
// + STACK/HOLD + LO FI sections. Cache shapes pin units; screenshot
|
|
405
|
+
// labels confirm names. Bypass_mode / kill_dry / phase_reverse /
|
|
406
|
+
// slopes / compander enums are hand-authored in params.ts.
|
|
407
|
+
13: { name: 'lr_time_ratio', unit: 'percent', displayMin: 1, displayMax: 100 },
|
|
408
|
+
16: { name: 'feedback_r', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
409
|
+
18: { name: 'stereo_spread', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
410
|
+
20: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
411
|
+
21: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
412
|
+
27: { name: 'input_gain', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
413
|
+
32: { name: 'master_feedback', unit: 'percent', displayMin: 0, displayMax: 200 },
|
|
414
|
+
47: { name: 'ducker_threshold', unit: 'db', displayMin: -80, displayMax: 20 },
|
|
415
|
+
48: { name: 'ducker_release', unit: 'ms', displayMin: 1, displayMax: 1000 },
|
|
416
|
+
49: { name: 'diffusor', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
417
|
+
50: { name: 'diffusion_time', unit: 'percent', displayMin: 1, displayMax: 100 },
|
|
418
|
+
63: { name: 'eq_q_high_low', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
419
|
+
64: { name: 'bit_reduction', unit: 'count', displayMin: 0, displayMax: 24 },
|
|
420
|
+
65: { name: 'eq_freq_1', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
421
|
+
66: { name: 'eq_freq_2', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
422
|
+
67: { name: 'eq_q_1', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
423
|
+
68: { name: 'eq_q_2', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
424
|
+
69: { name: 'eq_gain_1', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
425
|
+
70: { name: 'eq_gain_2', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
426
|
+
// HW-053 (2026-05-04): cache id=72 (DELAY_SPEED, "Motor Speed") has
|
|
427
|
+
// a=0.5, b=2, c=1 — a tape-motor speed multiplier, not dB. Without
|
|
428
|
+
// this hand override the cache pipeline emits unit='db' from the
|
|
429
|
+
// c=1 default. Range 0.5..2.0 = half-speed to double-speed; only
|
|
430
|
+
// applies when delay.type is Ping-Pong (per type-applicability).
|
|
431
|
+
72: { name: 'motor_speed', unit: 'count', displayMin: 0.5, displayMax: 2 },
|
|
432
|
+
76: { name: 'compander_time', unit: 'ms', displayMin: 1, displayMax: 100 },
|
|
433
|
+
77: { name: 'compander_threshold', unit: 'db', displayMin: -100, displayMax: -20 },
|
|
434
|
+
78: { name: 'master_time', unit: 'percent', displayMin: 25, displayMax: 400 },
|
|
435
|
+
79: { name: 'lfo_rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
436
|
+
80: { name: 'lfo_depth', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
437
|
+
87: { name: 'stack_feedback', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
438
|
+
88: { name: 'hold_feedback', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
439
|
+
// Session 88 (2026-05-16): DELAY params from
|
|
440
|
+
// samples/captured/decoded/am4-params-proposed.ts (Ghidra-mined
|
|
441
|
+
// catalog, Session 82–83). Same workflow as the REVERB block above:
|
|
442
|
+
// route through paramNames.ts overrides to correct the cache
|
|
443
|
+
// pipeline's c=1 → 'db' fallback for Hz / Q / count / degrees
|
|
444
|
+
// entries. Names use the resolver-derived GENERATED_PARAM_NAMES
|
|
445
|
+
// entries (firmware-truth) where they exist; ids with no GENERATED
|
|
446
|
+
// entry are enums that need custom value tables and stay
|
|
447
|
+
// hand-authored in params.ts (see TODOs below).
|
|
448
|
+
//
|
|
449
|
+
// id=17 DELAY_DELAYPAN ("Echo Pan") — c=100 a=-1 b=1 → bipolar
|
|
450
|
+
// pan, not a 0..100 percent. Generator default for c=100 is plain
|
|
451
|
+
// 'percent'; override to bipolar_percent.
|
|
452
|
+
17: { name: 'echo_pan', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
453
|
+
// ids 22/23 DELAY_RATE1/RATE2 ("Mod Rate" / "Rate") — cache type=66
|
|
454
|
+
// log10 a=0.1..10 / 0.2..20 → Hz. Default 'db' wrong.
|
|
455
|
+
22: { name: 'mod_rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
456
|
+
23: { name: 'rate', unit: 'hz', displayMin: 0.2, displayMax: 20 },
|
|
457
|
+
// ids 34/35 DELAY_FEEDLR/FEEDRL ("Rotation" / second routing) —
|
|
458
|
+
// c=100 a=-1 b=1 → bipolar_percent. Generator default is plain
|
|
459
|
+
// 'percent' which loses the sign.
|
|
460
|
+
34: { name: 'rotation', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
461
|
+
35: { name: 'lfo_phase', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
462
|
+
// ids 38/39 DELAY_PANL/PANR ("Pan L" / "Pan R") — type=48 c=100
|
|
463
|
+
// a=-1 b=1 → bipolar pan.
|
|
464
|
+
38: { name: 'pan_l', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
465
|
+
39: { name: 'pan_r', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
466
|
+
// ids 40/41 DELAY_LFO1PHASE/LFO2PHASE — type=54 c=57.29578 (rad→
|
|
467
|
+
// deg) → 0..180 degrees per radians-encoded LFO phase convention.
|
|
468
|
+
// Generator's c=57.29... is unrecognized; falls through to skip.
|
|
469
|
+
// Full override required.
|
|
470
|
+
40: { name: 'modulation_phase', unit: 'degrees', displayMin: 0, displayMax: 180 },
|
|
471
|
+
41: { name: 'lfo_phase_2', unit: 'degrees', displayMin: 0, displayMax: 180 },
|
|
472
|
+
// id=42 DELAY_SPLICETIME ("Crossfade Time") — type=52 c=1000
|
|
473
|
+
// a=0.001 b=0.255 → ms 1..255. Generator emits ms but displayMin
|
|
474
|
+
// floors to 0; override the lower bound to match cache.
|
|
475
|
+
42: { name: 'crossfade_time', unit: 'ms', displayMin: 1, displayMax: 255 },
|
|
476
|
+
// id=56 DELAY_RATE3 ("Sweep Rate") — type=66 → Hz; default 'db' wrong.
|
|
477
|
+
56: { name: 'sweep_rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
478
|
+
// id=58 DELAY_LFO3PHASE ("Sweep Phase") — type=54 → degrees.
|
|
479
|
+
58: { name: 'sweep_phase', unit: 'degrees', displayMin: 0, displayMax: 180 },
|
|
480
|
+
// ids 60/61 DELAY_FSTART/FSTOP ("Sweep Start/Stop Freq") — type=66
|
|
481
|
+
// → Hz; default 'db' wrong.
|
|
482
|
+
60: { name: 'sweep_start_freq', unit: 'hz', displayMin: 100, displayMax: 1000 },
|
|
483
|
+
61: { name: 'sweep_stop_freq', unit: 'hz', displayMin: 500, displayMax: 5000 },
|
|
484
|
+
// id=62 DELAY_Q ("Sweep Resonance") — type=80 log10 c=10 a=0.2
|
|
485
|
+
// b=20 → Q-factor 0.2..20. Cache c=10 makes generator emit
|
|
486
|
+
// 'knob_0_10' with bounds 0..10 — wrong upper bound and misleading
|
|
487
|
+
// unit name. Use 'count' with the real range.
|
|
488
|
+
62: { name: 'sweep_resonance', unit: 'count', displayMin: 0.2, displayMax: 20 },
|
|
489
|
+
// id=82 DELAY_RATE4 ("Pan Rate") — type=66 → Hz.
|
|
490
|
+
82: { name: 'pan_rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
491
|
+
// id=85 DELAY_LFO4PHASE — type=54 → degrees. GENERATED named it
|
|
492
|
+
// `lfo_phase_lfo4phase` (deduplication artifact); use the cleaner
|
|
493
|
+
// `lfo_phase_4` since LFO1 phase already owns plain `lfo_phase`.
|
|
494
|
+
85: { name: 'lfo_phase_4', unit: 'degrees', displayMin: 0, displayMax: 180 },
|
|
495
|
+
// TODO (no GENERATED entry, enum without value table — hand-author
|
|
496
|
+
// in params.ts with proper enum map):
|
|
497
|
+
// id=11 DELAY_TYPE enum 0..7 (delay mode variant)
|
|
498
|
+
// id=28 DELAY_LFO1TYPE enum 0..9 (LFO waveform: sine/tri/...)
|
|
499
|
+
// id=29 DELAY_LFO2TYPE enum 0..9 (LFO waveform)
|
|
500
|
+
// id=33 DELAY_TEMPOR enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
501
|
+
// id=43 DELAY_RUN enum 0..1 (run/stop toggle)
|
|
502
|
+
// id=44 DELAY_MODE enum 0..1 (mode toggle)
|
|
503
|
+
// id=52 DELAY_LFO1TARGET enum 0..2 (LFO 1 target)
|
|
504
|
+
// id=53 DELAY_LFO2TARGET enum 0..2 (LFO 2 target)
|
|
505
|
+
// id=54 DELAY_LFO1TEMPO enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
506
|
+
// id=55 DELAY_LFO2TEMPO enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
507
|
+
// id=57 DELAY_LFO3TYPE enum 0..9 (LFO waveform)
|
|
508
|
+
// id=59 DELAY_LFO3TEMPO enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
509
|
+
// id=71 DELAY_MAXDEPTH enum 0..1 (max depth toggle)
|
|
510
|
+
// id=81 DELAY_LFO4TYPE enum 0..9 (LFO waveform)
|
|
511
|
+
// id=83 DELAY_LFO4TEMPO enum 0..78 (TEMPO_DIVISIONS_VALUES)
|
|
512
|
+
// id=86 DELAY_LFO4TARGET enum 0..3 (LFO 4 target)
|
|
513
|
+
// id=89 DELAY_SVFTYPE enum 1..3 (SVF filter type)
|
|
514
|
+
},
|
|
515
|
+
// Universal `mix` at pidHigh 0x01 across every effect block that
|
|
516
|
+
// exposes a Mix Page per the Blocks Guide (p. 7). Skipped for
|
|
517
|
+
// Amp/Drive (different semantics), Wah/GEQ/Gate/VolPan (no wet/dry —
|
|
518
|
+
// AM4 manual p.34 line 1423: "Effects with no mix, such as Wah,
|
|
519
|
+
// GEQ, etc., will show 'NA'"). Cache signature matches percent
|
|
520
|
+
// (0..1 × 100) structurally identical to the confirmed reverb.mix.
|
|
521
|
+
// Modulation-block LFO controls. Blocks Guide §Chorus/Flanger/Phaser
|
|
522
|
+
// document "Rate (Hz/BPM): Controls the speed of the modulation" —
|
|
523
|
+
// all three blocks expose a rate knob with the same cache-c=1 raw-Hz
|
|
524
|
+
// signature. Depth is a percent knob at a distinct pidHigh per block.
|
|
525
|
+
chorus: {
|
|
526
|
+
1: 'mix',
|
|
527
|
+
2: BALANCE,
|
|
528
|
+
10: 'type',
|
|
529
|
+
12: { name: 'rate', unit: 'hz', displayMin: 0.1 },
|
|
530
|
+
14: 'depth',
|
|
531
|
+
// HW-040 (Session 36, 2026-04-29): Chorus Expert-Edit page on
|
|
532
|
+
// Analog Stereo from session-40-chorus-expert.pcapng. Cache shapes
|
|
533
|
+
// pin units; screenshot labels confirm names.
|
|
534
|
+
11: { name: 'number_of_voices', unit: 'count', displayMin: 1, displayMax: 4 },
|
|
535
|
+
15: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
536
|
+
21: { name: 'lfo_phase_pct', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
537
|
+
22: { name: 'lfo_rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
538
|
+
23: { name: 'width', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
539
|
+
24: { name: 'drive', unit: 'knob_0_10', displayMin: 0.5, displayMax: 500 },
|
|
540
|
+
25: { name: 'lfo_freq', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
541
|
+
26: { name: 'lfo_depth_2', unit: 'bipolar_percent', displayMin: -200, displayMax: 200 },
|
|
542
|
+
},
|
|
543
|
+
// geq Expert-Edit additions are merged into the existing geq:
|
|
544
|
+
// entry above (lines ~299) — duplicate removed in Session 36
|
|
545
|
+
// cleanup. The 10 GEQ bands + master_q now live there.
|
|
546
|
+
flanger: {
|
|
547
|
+
1: 'mix',
|
|
548
|
+
2: BALANCE,
|
|
549
|
+
10: 'type',
|
|
550
|
+
11: { name: 'rate', unit: 'hz', displayMin: 0.05 },
|
|
551
|
+
13: 'depth',
|
|
552
|
+
// Session 29 (HW-015): Feedback at pidHigh=0x0e. Cache (a=-0.995,
|
|
553
|
+
// b=0.995, c=100) — bipolar_percent with the internal range
|
|
554
|
+
// clamped slightly short of ±1.0 per Fractal's flanger
|
|
555
|
+
// implementation.
|
|
556
|
+
14: { name: 'feedback', unit: 'bipolar_percent', displayMin: -99, displayMax: 99 },
|
|
557
|
+
// Session 90 cont (2026-05-17): FLANGER unit overrides to correct
|
|
558
|
+
// the cache pipeline's c=1 → 'db' default for entries the catalog
|
|
559
|
+
// says are Hz / count / ms / knob. Names defer to GENERATED_PARAM_NAMES
|
|
560
|
+
// for ids the resolver covered (19/23/25/30/35) — only unit fixes
|
|
561
|
+
// emitted here. Source: paramNamesGenerated.ts + cache-section3.json
|
|
562
|
+
// ranges.
|
|
563
|
+
19: { name: 'smooth_steps', unit: 'count', displayMin: 0.5, displayMax: 50 },
|
|
564
|
+
23: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
565
|
+
25: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
566
|
+
35: { name: 'vpo_exponent', unit: 'count', displayMin: 0.01, displayMax: 100 },
|
|
567
|
+
},
|
|
568
|
+
phaser: {
|
|
569
|
+
1: 'mix',
|
|
570
|
+
2: BALANCE,
|
|
571
|
+
10: 'type',
|
|
572
|
+
12: { name: 'rate', unit: 'hz', displayMin: 0.1 },
|
|
573
|
+
// Session 29 (HW-015): Feedback at pidHigh=0x10. Cache (a=-0.9,
|
|
574
|
+
// b=0.9, c=111.1) — bipolar, internal ±0.9 with an unusual
|
|
575
|
+
// display-scale of 111.1 meaning internal -0.9 displays as
|
|
576
|
+
// -99.99%. We use the standard bipolar_percent unit (scale 100)
|
|
577
|
+
// with displayMin/Max clamped to ±90 so input stays within the
|
|
578
|
+
// internal range; the displayed percentage in AM4-Edit may read
|
|
579
|
+
// slightly higher than the value Claude used (e.g. "50" sets
|
|
580
|
+
// internal 0.5, AM4-Edit displays ~55.5%) but the wire behavior
|
|
581
|
+
// is correct. Natural-language UX impact is negligible.
|
|
582
|
+
16: { name: 'feedback', unit: 'bipolar_percent', displayMin: -90, displayMax: 90 },
|
|
583
|
+
// Session 90 cont (2026-05-17): PHASER unit overrides. Same
|
|
584
|
+
// cache-c=1 → 'db' default correction as flanger above. Names
|
|
585
|
+
// defer to GENERATED_PARAM_NAMES.
|
|
586
|
+
17: { name: 'min_frequency', unit: 'hz', displayMin: 5, displayMax: 500 },
|
|
587
|
+
18: { name: 'max_frequency', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
588
|
+
20: { name: 'bias', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
589
|
+
22: { name: 'feedback_point', unit: 'count', displayMin: 0, displayMax: 11 },
|
|
590
|
+
25: { name: 'q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
591
|
+
29: { name: 'shape_vcrk', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
592
|
+
30: { name: 'shape', unit: 'count', displayMin: 0.01, displayMax: 0.99 },
|
|
593
|
+
// id=31 high_cut: cache stores in kHz (0.5..50). 'count' until
|
|
594
|
+
// confirmed via capture — Hz unit would mislabel the display value.
|
|
595
|
+
31: { name: 'high_cut', unit: 'count', displayMin: 0.5, displayMax: 50 },
|
|
596
|
+
35: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 200 },
|
|
597
|
+
36: { name: 'high_cut_lpf', unit: 'hz', displayMin: 2000, displayMax: 20000 },
|
|
598
|
+
},
|
|
599
|
+
wah: {
|
|
600
|
+
1: 'mix',
|
|
601
|
+
2: BALANCE,
|
|
602
|
+
10: 'type',
|
|
603
|
+
// HW-040 (Session 36, 2026-04-29): Wah Expert-Edit page on FAS Wah
|
|
604
|
+
// from session-40-wah-expert.pcapng. Cache shapes pin units;
|
|
605
|
+
// screenshot labels confirm names. **BK-035 audit (Session 36 cont,
|
|
606
|
+
// 2026-04-29):** the original auto-generated names for ids 13..20
|
|
607
|
+
// were misaligned vs the AM4-Edit screenshot. Each label below was
|
|
608
|
+
// re-derived from the value-matched audit table run via
|
|
609
|
+
// `scripts/audit-block-vs-screenshot.ts` against
|
|
610
|
+
// `docs/audit-input/wah.json`. Old → new mapping:
|
|
611
|
+
// 13 (was `q`, range 2..20) → `q_resonance`, range 0..10
|
|
612
|
+
// 14 (was `q_resonance`) → `q_tracking`
|
|
613
|
+
// 15 (was `q_tracking`) → `wah_control`
|
|
614
|
+
// 16 (was `drive`) → `fat`
|
|
615
|
+
// 17 (was `fat`) → `drive`
|
|
616
|
+
// 18 (was unregistered) → `control_taper` (enum, hand-authored in params.ts)
|
|
617
|
+
// 19 (was `low_cut_frequency`) → `inductor_bias`
|
|
618
|
+
// 20 (was `inductor_bias`) → `low_cut_frequency`
|
|
619
|
+
11: { name: 'min_frequency', unit: 'hz', displayMin: 100, displayMax: 1000 },
|
|
620
|
+
12: { name: 'max_frequency', unit: 'hz', displayMin: 500, displayMax: 5000 },
|
|
621
|
+
13: { name: 'q_resonance', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
622
|
+
14: { name: 'q_tracking', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
623
|
+
15: { name: 'wah_control', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
624
|
+
16: { name: 'fat', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
625
|
+
17: { name: 'drive', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
626
|
+
19: { name: 'inductor_bias', unit: 'knob_0_10', displayMin: 0, displayMax: 10 },
|
|
627
|
+
20: { name: 'low_cut_frequency', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
628
|
+
22: { name: 'graphic_eq_band_1', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
629
|
+
23: { name: 'graphic_eq_band_2', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
630
|
+
24: { name: 'graphic_eq_band_3', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
631
|
+
25: { name: 'graphic_eq_band_4', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
632
|
+
26: { name: 'graphic_eq_band_5', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
633
|
+
27: { name: 'graphic_eq_band_6', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
634
|
+
28: { name: 'graphic_eq_band_7', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
635
|
+
29: { name: 'graphic_eq_band_8', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
636
|
+
},
|
|
637
|
+
// HW-040 (Session 36, 2026-04-29): NEW BLOCKS — PEQ (parametric EQ,
|
|
638
|
+
// pidLow=0x0036, S2 cacheBlock=4) and Rotary (pidLow=0x0056, S3
|
|
639
|
+
// cacheBlock=4). Neither has a Type enum at id=10. Captures from
|
|
640
|
+
// session-40-{peq,rot}-expert.pcapng.
|
|
641
|
+
peq: {
|
|
642
|
+
1: 'mix',
|
|
643
|
+
2: BALANCE,
|
|
644
|
+
// 5 channels of parametric EQ, each with Type / Frequency / Q /
|
|
645
|
+
// Gain / Solo. Cache lays them out in groups: ids 10-14 are the
|
|
646
|
+
// 5 frequencies (Hz, varying ranges), 15-19 are the 5 Q values
|
|
647
|
+
// (count 0.1..10), 20-24 are the 5 gains (dB ±20).
|
|
648
|
+
10: { name: 'channel_1_frequency', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
649
|
+
11: { name: 'channel_2_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
650
|
+
12: { name: 'channel_3_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
651
|
+
13: { name: 'channel_4_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
652
|
+
14: { name: 'channel_5_frequency', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
653
|
+
15: { name: 'channel_1_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
654
|
+
16: { name: 'channel_2_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
655
|
+
17: { name: 'channel_3_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
656
|
+
18: { name: 'channel_4_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
657
|
+
19: { name: 'channel_5_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
658
|
+
20: { name: 'channel_1_gain', unit: 'db', displayMin: -20, displayMax: 20 },
|
|
659
|
+
21: { name: 'channel_2_gain', unit: 'db', displayMin: -20, displayMax: 20 },
|
|
660
|
+
22: { name: 'channel_3_gain', unit: 'db', displayMin: -20, displayMax: 20 },
|
|
661
|
+
23: { name: 'channel_4_gain', unit: 'db', displayMin: -20, displayMax: 20 },
|
|
662
|
+
24: { name: 'channel_5_gain', unit: 'db', displayMin: -20, displayMax: 20 },
|
|
663
|
+
},
|
|
664
|
+
rotary: {
|
|
665
|
+
1: 'mix',
|
|
666
|
+
2: BALANCE,
|
|
667
|
+
// FAS Rotary cabinet sim. Cache layout (cacheBlock=4 in S3).
|
|
668
|
+
// **BK-035 audit (Session 36 cont, 2026-04-29):** initial cache-driven
|
|
669
|
+
// names had two pidHigh swaps vs the AM4-Edit screenshot. Re-derived
|
|
670
|
+
// via `scripts/audit-block-vs-screenshot.ts` against
|
|
671
|
+
// `docs/audit-input/rotary.json`:
|
|
672
|
+
// id 10 (was `drive`) → `rate` (Leslie speed knob; cache
|
|
673
|
+
// range 0..10 ×1 → display 0..10 Hz)
|
|
674
|
+
// id 21 (was `mic_spacing`) → `drive` (cache range 0.5..500 ×10)
|
|
675
|
+
// id 16 (was unregistered) → `mic_spacing` (cache π-encoded:
|
|
676
|
+
// range 0..π × 31.831 → display 0..100)
|
|
677
|
+
// Plus 5 new entries founder confirmed from screenshot:
|
|
678
|
+
// id 0 → `level` (db); id 4 → `bypass_mode` (enum, hand-authored
|
|
679
|
+
// in params.ts); id 14 → `tempo` (TEMPO_DIVISIONS, hand-authored);
|
|
680
|
+
// id 20 → `stereo_spread` (bipolar -200..200%); id 23 →
|
|
681
|
+
// `input_select` (enum [L+R, LEFT, RIGHT], hand-authored).
|
|
682
|
+
10: { name: 'rate', unit: 'hz', displayMin: 0, displayMax: 10 },
|
|
683
|
+
11: { name: 'low_depth', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
684
|
+
12: { name: 'high_depth', unit: 'percent', displayMin: 0, displayMax: 100 },
|
|
685
|
+
13: { name: 'high_level', unit: 'db', displayMin: -6, displayMax: 6 },
|
|
686
|
+
15: { name: 'rotor_length', unit: 'percent', displayMin: 0.1, displayMax: 100 },
|
|
687
|
+
16: { name: 'mic_spacing', unit: 'rotary_mic_spacing', displayMin: 0, displayMax: 100 },
|
|
688
|
+
17: { name: 'low_rate_multiplier', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
689
|
+
18: { name: 'low_time_constant', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
690
|
+
19: { name: 'high_time_constant', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
691
|
+
20: { name: 'stereo_spread', unit: 'bipolar_percent', displayMin: -200, displayMax: 200 },
|
|
692
|
+
21: { name: 'drive', unit: 'knob_0_10', displayMin: 0.5, displayMax: 500 },
|
|
693
|
+
22: { name: 'mic_distance', unit: 'count', displayMin: 0.01, displayMax: 1 },
|
|
694
|
+
},
|
|
695
|
+
compressor: {
|
|
696
|
+
1: 'mix',
|
|
697
|
+
2: BALANCE,
|
|
698
|
+
// HW-021 (Session 30, 2026-04-25): Compressor first-page knobs from
|
|
699
|
+
// session-30-comp-basic-jfet-studio. Cache ids 10..15 are the
|
|
700
|
+
// canonical comp-config registers per Blocks Guide §Compressor:
|
|
701
|
+
// Threshold (dB), Ratio (1..20:1, new `ratio` unit), Attack (ms),
|
|
702
|
+
// Release (ms), Knee Type enum (id 14, not yet wiggled), Auto
|
|
703
|
+
// Makeup OFF/ON (id 15, hand-authored in params.ts because per-
|
|
704
|
+
// block non-Type enums skip the generator). compressor.level
|
|
705
|
+
// (pidHigh=0x0000) is out-of-band hand-authored.
|
|
706
|
+
10: { name: 'threshold', unit: 'db', displayMin: -60, displayMax: 20 },
|
|
707
|
+
12: { name: 'attack', unit: 'ms', displayMin: 0.1, displayMax: 100 },
|
|
708
|
+
13: { name: 'release', unit: 'ms', displayMin: 2, displayMax: 2000 },
|
|
709
|
+
19: 'type',
|
|
710
|
+
// Ratio uses the new `ratio` unit (display = internal, scale 1) so
|
|
711
|
+
// Claude reads "ratio 4" as 4:1 not 4 dB. Cache c=1 default would
|
|
712
|
+
// mis-classify as dB; full override required.
|
|
713
|
+
11: { name: 'ratio', unit: 'ratio', displayMin: 1, displayMax: 20 },
|
|
714
|
+
// HW-028 + HW-039 (Session 35, 2026-04-29): JFET Studio Compressor
|
|
715
|
+
// Expert-Edit page exposes a Sidechain section + a Drive-engine
|
|
716
|
+
// emphasis knob. Decoded from session-31-comp-jfet-expert.pcapng
|
|
717
|
+
// + paired AM4-Edit screenshot. Cache shapes pin units; screenshot
|
|
718
|
+
// labels confirm the names. Wire-vs-screenshot value mismatches on
|
|
719
|
+
// Ratio (wire 2.22 / shot 3.000) and Look-Ahead (wire 4.33 ms / shot
|
|
720
|
+
// 2.000 ms) — founder noted screenshot was for label confirmation,
|
|
721
|
+
// not exact final-value sync; cache shapes + label position keep
|
|
722
|
+
// registration unambiguous. Closes HW-028 (0x0017 = emphasis at
|
|
723
|
+
// cache c=20 fine knob 0..20; 0x0029 = drive at cache c=10
|
|
724
|
+
// knob_0_10).
|
|
725
|
+
17: { name: 'sidechain_low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
726
|
+
21: { name: 'look_ahead_time', unit: 'ms', displayMin: 0, displayMax: 2 },
|
|
727
|
+
23: { name: 'emphasis', unit: 'knob_0_20', displayMin: 0, displayMax: 20 },
|
|
728
|
+
26: { name: 'sidechain_high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
729
|
+
27: { name: 'sidechain_gain', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
730
|
+
28: { name: 'sidechain_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
731
|
+
// Q is a fractional 0.1..10 quality factor — `count` here is
|
|
732
|
+
// structural (display = wire passthrough), not integer-only.
|
|
733
|
+
29: { name: 'sidechain_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
734
|
+
39: { name: 'sidechain_emphasis_freq', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
735
|
+
41: 'drive',
|
|
736
|
+
// Session 90 cont (2026-05-17): COMP ratio_compansion at id=36 is a
|
|
737
|
+
// ratio (1..10:1), not dB. Cache-c=1 default to 'db' was wrong.
|
|
738
|
+
36: { name: 'ratio_compansion', unit: 'ratio', displayMin: 1, displayMax: 10 },
|
|
739
|
+
},
|
|
740
|
+
geq: {
|
|
741
|
+
1: 'mix',
|
|
742
|
+
2: BALANCE,
|
|
743
|
+
20: 'type',
|
|
744
|
+
// HW-040 (Session 36, 2026-04-29): GEQ Expert-Edit page on
|
|
745
|
+
// 10 Band Variable Q from session-40-geq-expert.pcapng. 10 bands
|
|
746
|
+
// (cache ids 10-19), all bipolar dB ±12, plus Master Q (id 21).
|
|
747
|
+
// **BK-035 audit (Session 36 cont, 2026-04-29):** added Level
|
|
748
|
+
// (hand-authored in params.ts because pidHigh=0x0000 has no cache
|
|
749
|
+
// record at id=0 across blocks) and Bypass Mode (hand-authored enum).
|
|
750
|
+
10: { name: 'band_1', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
751
|
+
11: { name: 'band_2', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
752
|
+
12: { name: 'band_3', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
753
|
+
13: { name: 'band_4', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
754
|
+
14: { name: 'band_5', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
755
|
+
15: { name: 'band_6', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
756
|
+
16: { name: 'band_7', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
757
|
+
17: { name: 'band_8', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
758
|
+
18: { name: 'band_9', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
759
|
+
19: { name: 'band_10', unit: 'db', displayMin: -12, displayMax: 12 },
|
|
760
|
+
21: { name: 'master_q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
761
|
+
},
|
|
762
|
+
filter: {
|
|
763
|
+
1: 'mix',
|
|
764
|
+
2: BALANCE,
|
|
765
|
+
10: 'type',
|
|
766
|
+
// Blocks Guide §Filter: Frequency is the filter cutoff (20..20000 Hz
|
|
767
|
+
// at cache-c=1 raw). Universal control for every filter type.
|
|
768
|
+
11: { name: 'freq', unit: 'hz' },
|
|
769
|
+
// HW-032 (Session 30 cont 8, 2026-04-25): Low/High cut on the
|
|
770
|
+
// filter Config page — `session-32-filter-extended.pcapng`. Cache
|
|
771
|
+
// c=1 raw Hz; needs the 'hz' override since the generator default
|
|
772
|
+
// for c=1 is 'db'. Wire-verified at 100 Hz / 1800 Hz.
|
|
773
|
+
18: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
774
|
+
19: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
775
|
+
// HW-034 (Session 33, 2026-04-26): All-Pass filter Config-page
|
|
776
|
+
// residuals — `session-33-filter-extended.pcapng`. Wire-verified
|
|
777
|
+
// at +13% / 4 poles on an All-Pass filter. Feedback's cache
|
|
778
|
+
// signature (a=-1, b=1, c=100) requires the bipolar_percent
|
|
779
|
+
// override since the generator default for c=100 is plain
|
|
780
|
+
// percent. Order is a raw integer (cache c=1 a=1 b=12) — needs
|
|
781
|
+
// 'count' override since c=1 default is 'db'.
|
|
782
|
+
21: { name: 'feedback', unit: 'bipolar_percent', displayMin: -100, displayMax: 100 },
|
|
783
|
+
28: { name: 'order', unit: 'count', displayMin: 1, displayMax: 12 },
|
|
784
|
+
// HW-053 (2026-05-04): cache id=33 (FILTER_SENS, "Sensitivity") has
|
|
785
|
+
// a=0.1, b=40, c=10, typecode=80 (log10). The generator's c=10
|
|
786
|
+
// default forces displayMin=0, displayMax=10 (knob_0_10). With
|
|
787
|
+
// displayMin=0, the runtime decode falls back to LINEAR even when
|
|
788
|
+
// typecode 80 wants log10 — yielding the inverted-taper bug HW-053
|
|
789
|
+
// observed (write 7 → display 3.25). Override with a positive
|
|
790
|
+
// displayMin so log10 fires correctly. Only applies when
|
|
791
|
+
// filter.type is Envelope Filter / Auto-Wah / Touch-Wah (per
|
|
792
|
+
// type-applicability).
|
|
793
|
+
33: { name: 'sensitivity', unit: 'count', displayMin: 0.1, displayMax: 40 },
|
|
794
|
+
// Session 90 cont (2026-05-17): FILTER unit overrides. Same
|
|
795
|
+
// cache-c=1 → 'db' correction. id=33 sensitivity already overridden
|
|
796
|
+
// above per HW-053.
|
|
797
|
+
12: { name: 'q', unit: 'count', displayMin: 0.1, displayMax: 10 },
|
|
798
|
+
24: { name: 'rate', unit: 'hz', displayMin: 0.1, displayMax: 10 },
|
|
799
|
+
26: { name: 'mod_frequency', unit: 'hz', displayMin: 20, displayMax: 20000 },
|
|
800
|
+
31: { name: 'start_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
801
|
+
32: { name: 'stop_frequency', unit: 'hz', displayMin: 100, displayMax: 10000 },
|
|
802
|
+
},
|
|
803
|
+
tremolo: {
|
|
804
|
+
1: 'mix',
|
|
805
|
+
2: BALANCE,
|
|
806
|
+
10: 'type',
|
|
807
|
+
// Blocks Guide §Tremolo: Rate sets the modulation speed (0.2..20 Hz
|
|
808
|
+
// at cache-c=1 raw). Depth is a percent knob.
|
|
809
|
+
12: { name: 'rate', unit: 'hz', displayMin: 0.2 },
|
|
810
|
+
13: 'depth',
|
|
811
|
+
// Session 90 cont (2026-05-17): TREMOLO unit override — crossover
|
|
812
|
+
// freq is Hz not dB (cache-c=1 default).
|
|
813
|
+
21: { name: 'crossover_freq', unit: 'hz', displayMin: 200, displayMax: 2000 },
|
|
814
|
+
},
|
|
815
|
+
enhancer: {
|
|
816
|
+
1: 'mix',
|
|
817
|
+
2: BALANCE,
|
|
818
|
+
// HW-037 (Session 35, 2026-04-29): Config-page knobs from
|
|
819
|
+
// session-33-enhancer-extended.pcapng + paired screenshot. Wire-
|
|
820
|
+
// verified at width=33% / depth=11% / low_cut=22.2 Hz /
|
|
821
|
+
// high_cut=6500 Hz on a Modern enhancer. Width + Depth follow the
|
|
822
|
+
// generator's c=100 → percent default; Low/High Cut need the 'hz'
|
|
823
|
+
// override since cache c=1 default is dB. enhancer.level is out-of-
|
|
824
|
+
// band hand-authored in params.ts (pidHigh=0x0000, no cache record).
|
|
825
|
+
10: 'width',
|
|
826
|
+
11: 'depth',
|
|
827
|
+
12: { name: 'low_cut', unit: 'hz', displayMin: 20, displayMax: 2000 },
|
|
828
|
+
13: { name: 'high_cut', unit: 'hz', displayMin: 200, displayMax: 20000 },
|
|
829
|
+
// AM4-Edit labels this "Mode" but we keep `type` for cross-block consistency.
|
|
830
|
+
14: 'type',
|
|
831
|
+
},
|
|
832
|
+
gate: {
|
|
833
|
+
2: BALANCE,
|
|
834
|
+
// HW-035 (Session 34, 2026-04-26): slot-Gate Config-page knobs on
|
|
835
|
+
// Modern Gate type — `session-34-slotgate-extended.pcapng`.
|
|
836
|
+
// Threshold/Attack/Hold/Release/Attenuation are dB and ms knobs
|
|
837
|
+
// with cache c=1 (raw dB, signed) and c=1000 (ms) signatures
|
|
838
|
+
// respectively. Sidechain enum (cache id=15) is hand-authored
|
|
839
|
+
// in params.ts since the generator only handles one enum import
|
|
840
|
+
// per block (used for `type` at id=19).
|
|
841
|
+
10: { name: 'threshold', unit: 'db', displayMin: -100, displayMax: 0 },
|
|
842
|
+
11: { name: 'attack', unit: 'ms', displayMin: 0, displayMax: 1000 },
|
|
843
|
+
12: { name: 'hold', unit: 'ms', displayMin: 0, displayMax: 1000 },
|
|
844
|
+
13: { name: 'release', unit: 'ms', displayMin: 0, displayMax: 1000 },
|
|
845
|
+
19: 'type',
|
|
846
|
+
20: { name: 'attenuation', unit: 'db', displayMin: -80, displayMax: 0 },
|
|
847
|
+
},
|
|
848
|
+
volpan: {
|
|
849
|
+
2: BALANCE,
|
|
850
|
+
// The Volume-vs-Auto-Swell selector. Registered as `volpan.mode` in
|
|
851
|
+
// KNOWN_PARAMS for historical reasons — keep the name stable.
|
|
852
|
+
15: 'mode',
|
|
853
|
+
// HW-032 (Session 30 cont 8, 2026-04-25): Auto-Swell envelope params
|
|
854
|
+
// on the Volume/Pan Config page — `session-32-volpan-extended.pcapng`.
|
|
855
|
+
// Threshold (id=16, dB) wire-verified at -20 dB; Attack (id=17, ms)
|
|
856
|
+
// wire-verified at 300 ms. Cache c=1 for threshold (raw dB, needs
|
|
857
|
+
// 'db' override since generator default is also 'db' but we set the
|
|
858
|
+
// range explicitly). Cache c=1000 for attack means generator picks
|
|
859
|
+
// 'ms' automatically — no override needed except the display range.
|
|
860
|
+
16: { name: 'threshold', unit: 'db', displayMin: -100, displayMax: 0 },
|
|
861
|
+
17: { name: 'attack', unit: 'ms', displayMin: 1, displayMax: 5000 },
|
|
862
|
+
},
|
|
863
|
+
};
|