@audiofab-io/fv1-core 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/blocks/ATL_DEVELOPER_REFERENCE.md +156 -0
  2. package/blocks/control/constant.atl +36 -0
  3. package/blocks/control/entropy_lfo.atl +74 -0
  4. package/blocks/control/envelope.atl +121 -0
  5. package/blocks/control/invert.atl +33 -0
  6. package/blocks/control/pot.atl +150 -0
  7. package/blocks/control/power.atl +77 -0
  8. package/blocks/control/ramp_lfo.atl +122 -0
  9. package/blocks/control/scale_offset.atl +84 -0
  10. package/blocks/control/sincos_lfo.atl +126 -0
  11. package/blocks/control/smoother.atl +48 -0
  12. package/blocks/control/tremolizer.atl +55 -0
  13. package/blocks/effects/delay/micro_stutter.atl +77 -0
  14. package/blocks/effects/delay/mn3011.atl +281 -0
  15. package/blocks/effects/delay/simple_delay.atl +96 -0
  16. package/blocks/effects/delay/triple_tap_delay.atl +176 -0
  17. package/blocks/effects/lo-fi/bit_mangler.atl +74 -0
  18. package/blocks/effects/lo-fi/chiptune.atl +311 -0
  19. package/blocks/effects/lo-fi/tape_degrade.atl +181 -0
  20. package/blocks/effects/modulation/chorus.atl +141 -0
  21. package/blocks/effects/modulation/chorus_4voice.atl +188 -0
  22. package/blocks/effects/modulation/flanger.atl +184 -0
  23. package/blocks/effects/modulation/guitar_synth.atl +350 -0
  24. package/blocks/effects/modulation/harmonic_trem.atl +129 -0
  25. package/blocks/effects/modulation/organ_synth.atl +326 -0
  26. package/blocks/effects/modulation/phaser.atl +300 -0
  27. package/blocks/effects/pitch/octave_up_down.atl +80 -0
  28. package/blocks/effects/pitch/pitch_offset.atl +149 -0
  29. package/blocks/effects/pitch/pitch_offset_dual.atl +197 -0
  30. package/blocks/effects/pitch/pitch_shift.atl +115 -0
  31. package/blocks/effects/pitch/sub_octave.atl +100 -0
  32. package/blocks/effects/reverb/ducking_reverb.atl +145 -0
  33. package/blocks/effects/reverb/min_reverb.atl +132 -0
  34. package/blocks/effects/reverb/plate_reverb.atl +344 -0
  35. package/blocks/effects/reverb/room_reverb.atl +293 -0
  36. package/blocks/effects/reverb/smear.atl +90 -0
  37. package/blocks/effects/reverb/spring_reverb.atl +353 -0
  38. package/blocks/filter/1p_high_pass.atl +63 -0
  39. package/blocks/filter/1p_low_pass.atl +59 -0
  40. package/blocks/filter/auto_wah.atl +207 -0
  41. package/blocks/filter/bbd_loss.atl +79 -0
  42. package/blocks/filter/shelving_high_pass.atl +76 -0
  43. package/blocks/filter/shelving_low_pass.atl +76 -0
  44. package/blocks/filter/svf_2p.atl +116 -0
  45. package/blocks/gain_mix/crossfade.atl +93 -0
  46. package/blocks/gain_mix/crossfade2.atl +86 -0
  47. package/blocks/gain_mix/crossfade3.atl +71 -0
  48. package/blocks/gain_mix/gainboost.atl +54 -0
  49. package/blocks/gain_mix/mixer2.atl +76 -0
  50. package/blocks/gain_mix/mixer3.atl +109 -0
  51. package/blocks/gain_mix/mixer4.atl +152 -0
  52. package/blocks/gain_mix/volume.atl +51 -0
  53. package/blocks/io/adc.atl +53 -0
  54. package/blocks/io/dac.atl +61 -0
  55. package/blocks/other/stickynote.atl +24 -0
  56. package/blocks/other/tone_gen_adjustable.atl +137 -0
  57. package/blocks/other/tone_gen_fixed.atl +109 -0
  58. package/dist/blockDiagram/blocks/BlockDirectoryLoader.d.ts +13 -0
  59. package/dist/blockDiagram/blocks/BlockDirectoryLoader.d.ts.map +1 -0
  60. package/dist/blockDiagram/blocks/BlockDirectoryLoader.js +44 -0
  61. package/dist/blockDiagram/blocks/BlockDirectoryLoader.js.map +1 -0
  62. package/dist/blockDiagram/blocks/BlockRegistry.d.ts +48 -0
  63. package/dist/blockDiagram/blocks/BlockRegistry.d.ts.map +1 -0
  64. package/dist/blockDiagram/blocks/BlockRegistry.js +109 -0
  65. package/dist/blockDiagram/blocks/BlockRegistry.js.map +1 -0
  66. package/dist/blockDiagram/blocks/TemplateBlock.d.ts +20 -0
  67. package/dist/blockDiagram/blocks/TemplateBlock.d.ts.map +1 -0
  68. package/dist/blockDiagram/blocks/TemplateBlock.js +82 -0
  69. package/dist/blockDiagram/blocks/TemplateBlock.js.map +1 -0
  70. package/dist/blockDiagram/blocks/base/BaseBlock.d.ts +248 -0
  71. package/dist/blockDiagram/blocks/base/BaseBlock.d.ts.map +1 -0
  72. package/dist/blockDiagram/blocks/base/BaseBlock.js +402 -0
  73. package/dist/blockDiagram/blocks/base/BaseBlock.js.map +1 -0
  74. package/dist/blockDiagram/builtinBlocks.d.ts +9 -0
  75. package/dist/blockDiagram/builtinBlocks.d.ts.map +1 -0
  76. package/dist/blockDiagram/builtinBlocks.js +4912 -0
  77. package/dist/blockDiagram/builtinBlocks.js.map +1 -0
  78. package/dist/blockDiagram/compiler/BlockTemplate.d.ts +37 -0
  79. package/dist/blockDiagram/compiler/BlockTemplate.d.ts.map +1 -0
  80. package/dist/blockDiagram/compiler/BlockTemplate.js +860 -0
  81. package/dist/blockDiagram/compiler/BlockTemplate.js.map +1 -0
  82. package/dist/blockDiagram/compiler/CodeOptimizer.d.ts +75 -0
  83. package/dist/blockDiagram/compiler/CodeOptimizer.d.ts.map +1 -0
  84. package/dist/blockDiagram/compiler/CodeOptimizer.js +443 -0
  85. package/dist/blockDiagram/compiler/CodeOptimizer.js.map +1 -0
  86. package/dist/blockDiagram/compiler/GraphCompiler.d.ts +63 -0
  87. package/dist/blockDiagram/compiler/GraphCompiler.d.ts.map +1 -0
  88. package/dist/blockDiagram/compiler/GraphCompiler.js +656 -0
  89. package/dist/blockDiagram/compiler/GraphCompiler.js.map +1 -0
  90. package/dist/blockDiagram/compiler/TopologicalSort.d.ts +63 -0
  91. package/dist/blockDiagram/compiler/TopologicalSort.d.ts.map +1 -0
  92. package/dist/blockDiagram/compiler/TopologicalSort.js +268 -0
  93. package/dist/blockDiagram/compiler/TopologicalSort.js.map +1 -0
  94. package/dist/blockDiagram/index.d.ts +30 -0
  95. package/dist/blockDiagram/index.d.ts.map +1 -0
  96. package/dist/blockDiagram/index.js +29 -0
  97. package/dist/blockDiagram/index.js.map +1 -0
  98. package/dist/blockDiagram/types/Block.d.ts +178 -0
  99. package/dist/blockDiagram/types/Block.d.ts.map +1 -0
  100. package/dist/blockDiagram/types/Block.js +5 -0
  101. package/dist/blockDiagram/types/Block.js.map +1 -0
  102. package/dist/blockDiagram/types/CodeGenContext.d.ts +235 -0
  103. package/dist/blockDiagram/types/CodeGenContext.d.ts.map +1 -0
  104. package/dist/blockDiagram/types/CodeGenContext.js +554 -0
  105. package/dist/blockDiagram/types/CodeGenContext.js.map +1 -0
  106. package/dist/blockDiagram/types/Connection.d.ts +17 -0
  107. package/dist/blockDiagram/types/Connection.d.ts.map +1 -0
  108. package/dist/blockDiagram/types/Connection.js +5 -0
  109. package/dist/blockDiagram/types/Connection.js.map +1 -0
  110. package/dist/blockDiagram/types/Graph.d.ts +28 -0
  111. package/dist/blockDiagram/types/Graph.d.ts.map +1 -0
  112. package/dist/blockDiagram/types/Graph.js +24 -0
  113. package/dist/blockDiagram/types/Graph.js.map +1 -0
  114. package/dist/blockDiagram/types/IR.d.ts +79 -0
  115. package/dist/blockDiagram/types/IR.d.ts.map +1 -0
  116. package/dist/blockDiagram/types/IR.js +6 -0
  117. package/dist/blockDiagram/types/IR.js.map +1 -0
  118. package/dist/blockDiagram/utils/SpinCADConverter.d.ts +17 -0
  119. package/dist/blockDiagram/utils/SpinCADConverter.d.ts.map +1 -0
  120. package/dist/blockDiagram/utils/SpinCADConverter.js +307 -0
  121. package/dist/blockDiagram/utils/SpinCADConverter.js.map +1 -0
  122. package/dist/effect/compileEffect.d.ts +51 -0
  123. package/dist/effect/compileEffect.d.ts.map +1 -0
  124. package/dist/effect/compileEffect.js +133 -0
  125. package/dist/effect/compileEffect.js.map +1 -0
  126. package/dist/index.d.ts +2 -0
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +2 -0
  129. package/dist/index.js.map +1 -1
  130. package/package.json +17 -5
@@ -0,0 +1,281 @@
1
+ ---
2
+ {
3
+ "type": "effects.delay.mn3011",
4
+ "name": "MN3011 Multitap BBD Delay",
5
+ "category": "Effects",
6
+ "subcategory": "Delay",
7
+ "description": "Simulation of the classic MN3011 mult-tap BBD delay chip",
8
+ "color": "#6060c4",
9
+ "width": 230,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Audio In",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "fb_in",
19
+ "name": "Feedback",
20
+ "type": "audio",
21
+ "required": false
22
+ },
23
+ {
24
+ "id": "time_cv",
25
+ "name": "Delay Time",
26
+ "type": "control",
27
+ "required": false,
28
+ "parameter": "time"
29
+ },
30
+ {
31
+ "id": "fb_level_cv",
32
+ "name": "Feedback Level",
33
+ "type": "control",
34
+ "required": false,
35
+ "parameter": "fb_level"
36
+ }
37
+ ],
38
+ "outputs": [
39
+ {
40
+ "id": "mix",
41
+ "name": "Mix Out",
42
+ "type": "audio"
43
+ },
44
+ {
45
+ "id": "tap6",
46
+ "name": "Tap 6 Out",
47
+ "type": "audio"
48
+ }
49
+ ],
50
+ "parameters": [
51
+ {
52
+ "id": "input_gain",
53
+ "name": "Input Gain",
54
+ "type": "number",
55
+ "min": -24,
56
+ "max": 0,
57
+ "default": -6,
58
+ "conversion": "DBLEVEL",
59
+ "description": "Gain of the dry signal entering the delay line."
60
+ },
61
+ {
62
+ "id": "fb_level",
63
+ "name": "Feedback Level",
64
+ "type": "number",
65
+ "min": 0,
66
+ "max": 1,
67
+ "default": 0.5,
68
+ "step": 0.01,
69
+ "description": "Amount of feedback signal mixed in."
70
+ },
71
+ {
72
+ "id": "fbk_gain",
73
+ "name": "Feedback Gain",
74
+ "type": "number",
75
+ "min": -24,
76
+ "max": 0,
77
+ "default": -6,
78
+ "conversion": "DBLEVEL",
79
+ "description": "Master gain coefficient for the feedback loop."
80
+ },
81
+ {
82
+ "id": "time",
83
+ "name": "Delay Time (Scaling)",
84
+ "type": "number",
85
+ "min": 0,
86
+ "max": 1,
87
+ "default": 1.0,
88
+ "step": 0.01,
89
+ "description": "Global time scaling for all BBD taps (simulates clock rate)."
90
+ },
91
+ {
92
+ "id": "max_delay",
93
+ "name": "Max BBD Clock (ms)",
94
+ "type": "number",
95
+ "min": 1,
96
+ "max": 1000,
97
+ "default": 1000,
98
+ "conversion": "LENGTHTOTIME",
99
+ "description": "Maximum possible delay of the longest tap (3328 stages)."
100
+ },
101
+ {
102
+ "id": "tap1_gain",
103
+ "name": "Tap 1 Gain",
104
+ "type": "number",
105
+ "min": -24,
106
+ "max": 0,
107
+ "default": -6,
108
+ "conversion": "DBLEVEL"
109
+ },
110
+ {
111
+ "id": "tap2_gain",
112
+ "name": "Tap 2 Gain",
113
+ "type": "number",
114
+ "min": -24,
115
+ "max": 0,
116
+ "default": -6,
117
+ "conversion": "DBLEVEL"
118
+ },
119
+ {
120
+ "id": "tap3_gain",
121
+ "name": "Tap 3 Gain",
122
+ "type": "number",
123
+ "min": -24,
124
+ "max": 0,
125
+ "default": -6,
126
+ "conversion": "DBLEVEL"
127
+ },
128
+ {
129
+ "id": "tap4_gain",
130
+ "name": "Tap 4 Gain",
131
+ "type": "number",
132
+ "min": -24,
133
+ "max": 0,
134
+ "default": -6,
135
+ "conversion": "DBLEVEL"
136
+ },
137
+ {
138
+ "id": "tap5_gain",
139
+ "name": "Tap 5 Gain",
140
+ "type": "number",
141
+ "min": -24,
142
+ "max": 0,
143
+ "default": -6,
144
+ "conversion": "DBLEVEL"
145
+ },
146
+ {
147
+ "id": "tap6_gain",
148
+ "name": "Tap 6 Gain",
149
+ "type": "number",
150
+ "min": -24,
151
+ "max": 0,
152
+ "default": -6,
153
+ "conversion": "DBLEVEL"
154
+ }
155
+ ],
156
+ "registers": [
157
+ "pot_val",
158
+ "mix_acc",
159
+ "tap_out"
160
+ ],
161
+ "memories": [
162
+ {
163
+ "id": "buffer",
164
+ "size": "max_delay"
165
+ }
166
+ ]
167
+ }
168
+ ---
169
+ @section header
170
+ ; MN3011 Target Ratios (stage / 3328)
171
+ equ t1_ratio 0.118990 ; 396/3328
172
+ equ t2_ratio 0.198918 ; 662/3328
173
+ equ t3_ratio 0.358774 ; 1194/3328
174
+ equ t4_ratio 0.518630 ; 1726/3328
175
+ equ t5_ratio 0.838341 ; 2790/3328
176
+ equ t6_ratio 1.0 ; 3328/3328
177
+
178
+ @section main
179
+ ; 1. Feedback Processing
180
+ @if pinConnected(fb_in)
181
+ rdax ${input.fb_in}, 1.0
182
+ @mulcv fb_level_cv
183
+ sof ${param.fbk_gain}, 0.0
184
+ @else
185
+ clr
186
+ @endif
187
+
188
+ ; 2. Input Summing & Write
189
+ rdax ${input.in}, ${param.input_gain}
190
+ wra ${mem.buffer}, 0.0
191
+
192
+ ; 3. Multitap Summation
193
+ @if pinConnected(time_cv)
194
+ ; --- Dynamic Time (ADDR_PTR mode) ---
195
+ @cv time_cv
196
+ wrax ${reg.pot_val}, 0.0
197
+
198
+ ; Tap 6 (processed first for fb_out convenience)
199
+ rdax ${reg.pot_val}, 1.0
200
+ sof t6_ratio, 0
201
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
202
+ wrax ADDR_PTR, 0
203
+ rmpa 1.0
204
+ @if pinConnected(tap6)
205
+ wrax ${output.tap6}, 1.0
206
+ @endif
207
+ sof ${param.tap6_gain}, 0.0
208
+ wrax ${reg.mix_acc}, 0.0
209
+
210
+ ; Tap 1
211
+ rdax ${reg.pot_val}, 1.0
212
+ sof t1_ratio, 0
213
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
214
+ wrax ADDR_PTR, 0
215
+ rmpa ${param.tap1_gain}
216
+ rdax ${reg.mix_acc}, 1.0
217
+ wrax ${reg.mix_acc}, 0.0
218
+
219
+ ; Tap 2
220
+ rdax ${reg.pot_val}, 1.0
221
+ sof t2_ratio, 0
222
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
223
+ wrax ADDR_PTR, 0
224
+ rmpa ${param.tap2_gain}
225
+ rdax ${reg.mix_acc}, 1.0
226
+ wrax ${reg.mix_acc}, 0.0
227
+
228
+ ; Tap 3
229
+ rdax ${reg.pot_val}, 1.0
230
+ sof t3_ratio, 0
231
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
232
+ wrax ADDR_PTR, 0
233
+ rmpa ${param.tap3_gain}
234
+ rdax ${reg.mix_acc}, 1.0
235
+ wrax ${reg.mix_acc}, 0.0
236
+
237
+ ; Tap 4
238
+ rdax ${reg.pot_val}, 1.0
239
+ sof t4_ratio, 0
240
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
241
+ wrax ADDR_PTR, 0
242
+ rmpa ${param.tap4_gain}
243
+ rdax ${reg.mix_acc}, 1.0
244
+ wrax ${reg.mix_acc}, 0.0
245
+
246
+ ; Tap 5
247
+ rdax ${reg.pot_val}, 1.0
248
+ sof t5_ratio, 0
249
+ sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)
250
+ wrax ADDR_PTR, 0
251
+ rmpa ${param.tap5_gain}
252
+ rdax ${reg.mix_acc}, 1.0
253
+
254
+ @else
255
+ ; --- Static Time (Fixed RDA mode) ---
256
+
257
+ ; Tap 6
258
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t6_ratio), 1.0
259
+ @if pinConnected(tap6)
260
+ wrax ${output.tap6}, 1.0
261
+ @endif
262
+ sof ${param.tap6_gain}, 0.0
263
+
264
+ ; Tap 5
265
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t5_ratio), ${param.tap5_gain}
266
+
267
+ ; Tap 4
268
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t4_ratio), ${param.tap4_gain}
269
+
270
+ ; Tap 3
271
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t3_ratio), ${param.tap3_gain}
272
+
273
+ ; Tap 2
274
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t2_ratio), ${param.tap2_gain}
275
+
276
+ ; Tap 1
277
+ rda ${mem.buffer} + (${max_delay} * ${param.time} * t1_ratio), ${param.tap1_gain}
278
+ @endif
279
+
280
+ ; 4. Export Final Mix
281
+ wrax ${output.mix}, 0.0
@@ -0,0 +1,96 @@
1
+ ---
2
+ {
3
+ "type": "effects.delay.simple",
4
+ "name": "Simple Delay",
5
+ "category": "Effects",
6
+ "subcategory": "Delay",
7
+ "description": "Simple delay line with variable time and mix control",
8
+ "color": "#6060c4",
9
+ "width": 180,
10
+ "inputs": [
11
+ {
12
+ "id": "audio_input",
13
+ "name": "Audio Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "delay_time",
19
+ "name": "Delay Time",
20
+ "type": "control",
21
+ "required": false,
22
+ "parameter": "delayLength"
23
+ },
24
+ {
25
+ "id": "mix_ctrl",
26
+ "name": "Mix",
27
+ "type": "control",
28
+ "required": false,
29
+ "parameter": "mix"
30
+ }
31
+ ],
32
+ "outputs": [
33
+ {
34
+ "id": "audio_output",
35
+ "name": "Audio Output",
36
+ "type": "audio"
37
+ }
38
+ ],
39
+ "parameters": [
40
+ {
41
+ "id": "delayLength",
42
+ "name": "Delay Length (ms)",
43
+ "type": "number",
44
+ "default": 500,
45
+ "min": 1,
46
+ "max": 1000,
47
+ "conversion": "MS_TO_SAMPLES",
48
+ "description": "The delay time in milliseconds. Determines the maximum possible delay time when controlled via a control signal.",
49
+ "step": 1
50
+ },
51
+ {
52
+ "id": "mix",
53
+ "name": "Mix",
54
+ "type": "number",
55
+ "default": 0.5,
56
+ "min": 0,
57
+ "max": 1,
58
+ "step": 0.01,
59
+ "description": "Dry/Wet mix balance. 0.0 is pure dry, 1.0 is pure wet."
60
+ }
61
+ ],
62
+ "memories": [
63
+ {
64
+ "id": "delayl",
65
+ "size": "delayLength"
66
+ }
67
+ ],
68
+ "registers": [
69
+ "dry",
70
+ "wet"
71
+ ]
72
+ }
73
+ ---
74
+ ; Simple Delay with Mix
75
+ ; Store dry signal and write to delay
76
+ rdax ${input.audio_input}, 1.0
77
+ wrax ${reg.dry}, 1.0
78
+ wra ${mem.delayl}, 0.0
79
+
80
+ ; Calculate Delay Pointer (ADDR_PTR is an absolute address in delay RAM)
81
+ @cv delay_time
82
+ ; Control sweeps from [base] to [base + size]
83
+ sof ${delayLength}/${Fs}, (${mem.delayl} + 1)/${Fs}
84
+ wrax ADDR_PTR, 0.0
85
+
86
+ ; Read wet signal
87
+ rmpa 1.0
88
+
89
+ ; Mixing logic: dry + mix * (wet - dry)
90
+ rdax ${reg.dry}, -0.999 ; ACC now equals (wet - dry)
91
+ wrax ${reg.wet}, 0.0 ; Store wet-dry in reg.wet temporarily
92
+
93
+ @cv mix_ctrl
94
+ mulx ${reg.wet}
95
+ rdax ${reg.dry}, 1.0
96
+ wrax ${output.audio_output}, 0.0
@@ -0,0 +1,176 @@
1
+ ---
2
+ {
3
+ "type": "fx.delay.tripletap",
4
+ "name": "ThreeTap",
5
+ "category": "Effects",
6
+ "subcategory": "Delay",
7
+ "description": "Triple tap delay with independent outputs and CV modulation",
8
+ "color": "#6060c4",
9
+ "width": 200,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "feedback",
19
+ "name": "Feedback",
20
+ "type": "audio",
21
+ "required": false
22
+ },
23
+ {
24
+ "id": "delay_time_1",
25
+ "name": "Delay Time 1",
26
+ "type": "control",
27
+ "required": false,
28
+ "parameter": "tap1Time"
29
+ },
30
+ {
31
+ "id": "delay_time_2",
32
+ "name": "Delay Time 2",
33
+ "type": "control",
34
+ "required": false,
35
+ "parameter": "tap2Time"
36
+ },
37
+ {
38
+ "id": "delay_time_3",
39
+ "name": "Delay Time 3",
40
+ "type": "control",
41
+ "required": false,
42
+ "parameter": "tap3Time"
43
+ },
44
+ {
45
+ "id": "fbk_ctrl",
46
+ "name": "Feedback Gain",
47
+ "type": "control",
48
+ "required": false,
49
+ "parameter": "fbkGain"
50
+ }
51
+ ],
52
+ "outputs": [
53
+ {
54
+ "id": "tap1",
55
+ "name": "Tap 1 Out",
56
+ "type": "audio"
57
+ },
58
+ {
59
+ "id": "tap2",
60
+ "name": "Tap 2 Out",
61
+ "type": "audio"
62
+ },
63
+ {
64
+ "id": "tap3",
65
+ "name": "Tap 3 Out",
66
+ "type": "audio"
67
+ }
68
+ ],
69
+ "parameters": [
70
+ {
71
+ "id": "inputGain",
72
+ "name": "Input Gain (dB)",
73
+ "type": "number",
74
+ "default": 0,
75
+ "min": -24,
76
+ "max": 0,
77
+ "conversion": "DBLEVEL",
78
+ "step": 0.01
79
+ },
80
+ {
81
+ "id": "fbkGain",
82
+ "name": "Feedback Gain (dB)",
83
+ "type": "number",
84
+ "default": -6,
85
+ "min": -24,
86
+ "max": 0,
87
+ "conversion": "DBLEVEL",
88
+ "step": 0.01
89
+ },
90
+ {
91
+ "id": "delayTime",
92
+ "name": "Total Delay (ms)",
93
+ "type": "number",
94
+ "default": 1000,
95
+ "min": 10,
96
+ "max": 1000,
97
+ "conversion": "MS_TO_SAMPLES",
98
+ "description": "The total delay memory allocated in ms.",
99
+ "step": 1
100
+ },
101
+ {
102
+ "id": "tap1Time",
103
+ "name": "Tap 1 Time",
104
+ "type": "number",
105
+ "default": 0.85,
106
+ "min": 0.0,
107
+ "max": 1.0,
108
+ "step": 0.01
109
+ },
110
+ {
111
+ "id": "tap2Time",
112
+ "name": "Tap 2 Time",
113
+ "type": "number",
114
+ "default": 0.60,
115
+ "min": 0.0,
116
+ "max": 1.0,
117
+ "step": 0.01
118
+ },
119
+ {
120
+ "id": "tap3Time",
121
+ "name": "Tap 3 Time",
122
+ "type": "number",
123
+ "default": 0.45,
124
+ "min": 0.0,
125
+ "max": 1.0,
126
+ "step": 0.01
127
+ }
128
+ ],
129
+ "memories": [
130
+ {
131
+ "id": "delayl",
132
+ "size": "delayTime"
133
+ }
134
+ ],
135
+ "registers": [
136
+ "temp"
137
+ ]
138
+ }
139
+ ---
140
+ ; ThreeTap Delay
141
+ @if pinConnected(feedback)
142
+ rdax ${input.feedback}, 1.0 ; Read at unity — @cv fbk_ctrl applies the gain scaling below
143
+ wrax ${reg.temp}, 0.0
144
+ @cv fbk_ctrl ; ACC = fbkGain_linear * pot (or just fbkGain_linear if unconnected)
145
+ mulx ${reg.temp} ; ACC = feedback * fbkGain [* pot]
146
+ @endif
147
+ rdax ${input.in}, ${inputGain}
148
+ wra ${mem.delayl}, 0.0
149
+
150
+ @if pinConnected(tap1)
151
+ ; Tap 1
152
+ @cv delay_time_1
153
+ sof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})
154
+ wrax ADDR_PTR, 0.0
155
+ rmpa 1.0
156
+ wrax ${output.tap1}, 0.0
157
+ @endif
158
+
159
+ @if pinConnected(tap2)
160
+ ; Tap 2
161
+ @cv delay_time_2
162
+ sof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})
163
+ wrax ADDR_PTR, 0.0
164
+ rmpa 1.0
165
+ wrax ${output.tap2}, 0.0
166
+ @endif
167
+
168
+ @if pinConnected(tap3)
169
+ ; Tap 3
170
+ @cv delay_time_3
171
+ sof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})
172
+ wrax ADDR_PTR, 0.0
173
+ rmpa 1.0
174
+ wrax ${output.tap3}, 0.0
175
+ @endif
176
+
@@ -0,0 +1,74 @@
1
+ ---
2
+ {
3
+ "type": "effects.bit_mangler",
4
+ "name": "The Bit-Mangler",
5
+ "category": "Effects",
6
+ "subcategory": "Lo-Fi",
7
+ "description": "An enveloped sample-rate reducer (Fixed: Namespaced labels and gain staging).",
8
+ "color": "#6f24f2",
9
+ "inputs": [
10
+ { "id": "input", "name": "Audio In", "type": "audio" },
11
+ { "id": "sensCV", "name": "Sensitivity", "type": "control", "required": false, "parameter": "sens" },
12
+ { "id": "mixCV", "name": "Mix", "type": "control", "required": false, "parameter": "mix" }
13
+ ],
14
+ "outputs": [
15
+ { "id": "out", "name": "Audio Out", "type": "audio" }
16
+ ],
17
+ "parameters": [
18
+ { "id": "base_rate", "name": "Crush Step", "type": "number", "default": 0.05, "min": 0, "max": 0.5, "step": 0.001 },
19
+ { "id": "sens", "name": "Env Sensitivity", "type": "number", "default": 0.1, "min": 0, "max": 1, "step": 0.01 },
20
+ { "id": "mix", "name": "Dry/Wet Mix", "type": "number", "default": 1.0, "min": 0, "max": 1, "step": 0.01 }
21
+ ],
22
+ "registers": [ "env", "counter", "held", "temp_mix", "dry_val" ]
23
+ }
24
+ ---
25
+ ; The Bit-Mangler - Namespaced SRR
26
+ ; Fixes jump collisions and hardware register leakage (Register 0).
27
+
28
+ @section main
29
+ @if pinConnected(input)
30
+ ; 0. Initialization (First Run only)
31
+ skp run, ${local.SKIP_INIT}
32
+ rdax ${input.input}, 1.0
33
+ wrax ${reg.held}, 0.0
34
+ ${local.SKIP_INIT}:
35
+
36
+ ; 1. Envelope Follower
37
+ clr
38
+ rdax ${input.input}, 1.0
39
+ absa
40
+ rdfx ${reg.env}, 0.001
41
+ wrax ${reg.env}, 0.0
42
+
43
+ ; 2. S&H Counter
44
+ ; Increment = base_rate + (env * sens)
45
+ @cv sensCV ; ACC = sensCV
46
+ mulx ${reg.env} ; ACC = sensCV * env
47
+ rdax ${reg.counter}, 1.0 ; ACC = (sensCV * env) + counter
48
+ sof 1.0, ${param.base_rate} ; ACC = (sensCV * env) + counter + base_rate
49
+ wrax ${reg.counter}, 1.0
50
+
51
+ ; 3. Check for Sample Event (trigger at 0.99)
52
+ sof 1.0, -0.99
53
+ skp neg, ${local.SKIP_SAMPLE}
54
+
55
+ ; --- Sample Block (Runs only on Trigger) ---
56
+ clr ; MUST clear ACC to avoid using the 'counter-0.95' residual!
57
+ rdax ${input.input}, 1.0
58
+ wrax ${reg.held}, 0.0 ; Update S&H value
59
+ sof 0.0, 0.0
60
+ wrax ${reg.counter}, 0.0 ; Reset counter
61
+
62
+ ${local.SKIP_SAMPLE}:
63
+ ; 4. Final Output Mix: Out = Dry + (Wet - Dry) * Mix
64
+ clr ; Clear ACC after skip to avoid counter pollution
65
+ @cv mixCV ; Load mix value (0 to 1)
66
+ wrax ${reg.temp_mix}, 0.0
67
+
68
+ rdax ${input.input}, 1.0 ; Dry signal
69
+ wrax ${reg.dry_val}, -1.0 ; dry_val = dry, ACC = -dry
70
+ rdax ${reg.held}, 1.0 ; ACC = wet - dry
71
+ mulx ${reg.temp_mix} ; ACC = (wet - dry) * mix
72
+ rdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix
73
+ wrax ${output.out}, 0.0
74
+ @endif