@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,326 @@
1
+ ---
2
+ {
3
+ "type": "effects.modulation.organ_synth",
4
+ "name": "Organ Synth",
5
+ "category": "Effects",
6
+ "subcategory": "Modulation",
7
+ "description": "Tonewheel organ emulator inspired by the EHX B9. Generates octave-up, fundamental, and sub-octave voices like organ drawbars, with a tonewheel tone filter and optional rotary vibrato. Play single notes for the best tracking.",
8
+ "color": "#CC6633",
9
+ "width": 180,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "rate_cv",
19
+ "name": "Vibrato Rate",
20
+ "type": "control",
21
+ "required": false,
22
+ "parameter": "vibrato_rate"
23
+ },
24
+ {
25
+ "id": "depth_cv",
26
+ "name": "Vibrato Depth",
27
+ "type": "control",
28
+ "required": false,
29
+ "parameter": "vibrato_depth"
30
+ },
31
+ {
32
+ "id": "tone_cv",
33
+ "name": "Tone",
34
+ "type": "control",
35
+ "required": false,
36
+ "parameter": "tone"
37
+ },
38
+ {
39
+ "id": "mix_cv",
40
+ "name": "Mix",
41
+ "type": "control",
42
+ "required": false,
43
+ "parameter": "mix"
44
+ }
45
+ ],
46
+ "outputs": [
47
+ {
48
+ "id": "out",
49
+ "name": "Output",
50
+ "type": "audio"
51
+ }
52
+ ],
53
+ "parameters": [
54
+ {
55
+ "id": "upper",
56
+ "name": "Upper (Oct Up)",
57
+ "type": "number",
58
+ "default": 0.6,
59
+ "min": 0.0,
60
+ "max": 1.5,
61
+ "step": 0.05,
62
+ "description": "Level of the +1 octave voice (4' drawbar). Adds brightness and presence."
63
+ },
64
+ {
65
+ "id": "fundamental",
66
+ "name": "Fundamental",
67
+ "type": "number",
68
+ "default": 0.8,
69
+ "min": 0.0,
70
+ "max": 1.5,
71
+ "step": 0.05,
72
+ "description": "Level of the fundamental voice (8' drawbar). The core organ tone."
73
+ },
74
+ {
75
+ "id": "sub",
76
+ "name": "Sub (Oct Down)",
77
+ "type": "number",
78
+ "default": 0.5,
79
+ "min": 0.0,
80
+ "max": 1.5,
81
+ "step": 0.05,
82
+ "description": "Level of the -1 octave voice (16' drawbar). Adds bass organ weight."
83
+ },
84
+ {
85
+ "id": "drive",
86
+ "name": "Key Click / Drive",
87
+ "type": "number",
88
+ "default": 0.8,
89
+ "min": 0.0,
90
+ "max": 1.99,
91
+ "step": 0.01,
92
+ "description": "Waveshaping intensity. Shapes the guitar into a rounder, more organ-like waveform. Higher values add harmonic grit like an overdriven Hammond."
93
+ },
94
+ {
95
+ "id": "tone",
96
+ "name": "Tone",
97
+ "type": "number",
98
+ "default": 2500,
99
+ "min": 300,
100
+ "max": 6000,
101
+ "step": 10,
102
+ "conversion": "SVFFREQ",
103
+ "description": "Master lowpass filter. Roll off for a warm jazz organ, open up for a bright rock organ."
104
+ },
105
+ {
106
+ "id": "vibrato_rate",
107
+ "name": "Vibrato Rate (Hz)",
108
+ "type": "number",
109
+ "default": 6.0,
110
+ "min": 0.5,
111
+ "max": 10.0,
112
+ "step": 0.1,
113
+ "conversion": "HZ_TO_LFO_RATE",
114
+ "description": "Rotary/vibrato speed. ~6 Hz for classic Leslie slow, ~8 Hz for fast."
115
+ },
116
+ {
117
+ "id": "vibrato_depth",
118
+ "name": "Vibrato Depth (ms)",
119
+ "type": "number",
120
+ "default": 1.0,
121
+ "min": 0.0,
122
+ "max": 5.0,
123
+ "step": 0.1,
124
+ "conversion": "MS_TO_LFO_RANGE",
125
+ "description": "Rotary/vibrato depth. Subtle values (~0.5-1 ms) for chorus-vibrato, higher for full Leslie warble."
126
+ },
127
+ {
128
+ "id": "mix",
129
+ "name": "Dry/Wet Mix",
130
+ "type": "number",
131
+ "default": 1.0,
132
+ "min": 0.0,
133
+ "max": 1.0,
134
+ "step": 0.01
135
+ }
136
+ ],
137
+ "memories": [
138
+ {
139
+ "id": "sub_buf",
140
+ "size": 4096
141
+ },
142
+ {
143
+ "id": "sub_temp",
144
+ "size": 1
145
+ },
146
+ {
147
+ "id": "up_buf",
148
+ "size": 4096
149
+ },
150
+ {
151
+ "id": "up_temp",
152
+ "size": 1
153
+ },
154
+ {
155
+ "id": "vib_buf",
156
+ "size": 512
157
+ }
158
+ ],
159
+ "registers": [
160
+ "shaped",
161
+ "sub_lp1",
162
+ "sub_lp2",
163
+ "tone_lp1",
164
+ "tone_lp2",
165
+ "tone_freq",
166
+ "vib_out",
167
+ "dry",
168
+ "mix_reg"
169
+ ]
170
+ }
171
+ ---
172
+ @section header
173
+ @equals vib_center ${mem.vib_buf} + 256
174
+
175
+ @section init
176
+ skp run, done_init
177
+ ; RMP0: sub-octave (-1 oct, rate -8192)
178
+ wldr RMP0, -8192, 4096
179
+ ; RMP1: octave up (+1 oct, rate 16384)
180
+ wldr RMP1, 16384, 4096
181
+ ; SIN0: rotary vibrato
182
+ wlds SIN0, ${param.vibrato_rate}, ${param.vibrato_depth}
183
+ done_init:
184
+
185
+ @section main
186
+ @if pinConnected(in)
187
+
188
+ ; ======================================================
189
+ ; Stage 0: Save dry signal
190
+ ; ======================================================
191
+ rdax ${input.in}, 1.0
192
+ wrax ${reg.dry}, 0.0
193
+
194
+ ; ======================================================
195
+ ; Stage 1: Waveshaping (organ-like waveform)
196
+ ; Soft clipping via cascaded saturation — rounds the
197
+ ; guitar waveform toward a smoother, organ-like shape.
198
+ ; ======================================================
199
+ rdax ${input.in}, 1.0
200
+ sof 1.99, 0.0
201
+ sof -1.99, 0.0
202
+ sof -1.99, 0.0
203
+ sof 0.5, 0.0
204
+ wrax ${reg.shaped}, 0.0
205
+
206
+ ; Crossfade: out = input + (shaped - input) * drive
207
+ rdax ${reg.shaped}, 1.0
208
+ rdax ${input.in}, -1.0
209
+ sof ${param.drive}, 0.0
210
+ rdax ${input.in}, 1.0
211
+ wrax ${reg.shaped}, 0.0
212
+
213
+ ; ======================================================
214
+ ; Stage 2: Write shaped signal to both pitch shift buffers
215
+ ; ======================================================
216
+ rdax ${reg.shaped}, 1.0
217
+ wra ${mem.sub_buf}, 0.0
218
+ rdax ${reg.shaped}, 1.0
219
+ wra ${mem.up_buf}, 0.0
220
+
221
+ ; ======================================================
222
+ ; Stage 3: Sub-Octave / 16' drawbar (RMP0, -1 oct)
223
+ ; ======================================================
224
+ cho rda, RMP0, REG | COMPC, ${mem.sub_buf}
225
+ cho rda, RMP0, 0, ${mem.sub_buf} + 1
226
+ wra ${mem.sub_temp}, 0.0
227
+ cho rda, RMP0, RPTR2 | COMPC, ${mem.sub_buf}
228
+ cho rda, RMP0, RPTR2, ${mem.sub_buf} + 1
229
+ cho sof, RMP0, NA | COMPC, 0.0
230
+ cho rda, RMP0, NA, ${mem.sub_temp}
231
+
232
+ ; 2-pole lowpass to smooth sub artifacts
233
+ rdax ${reg.sub_lp1}, -1.0
234
+ sof 0.15, 0.0
235
+ rdax ${reg.sub_lp1}, 1.0
236
+ wrax ${reg.sub_lp1}, 1.0
237
+
238
+ rdax ${reg.sub_lp2}, -1.0
239
+ sof 0.15, 0.0
240
+ rdax ${reg.sub_lp2}, 1.0
241
+ wrax ${reg.sub_lp2}, 1.0
242
+
243
+ ; Scale by sub level
244
+ sof ${param.sub}, 0.0
245
+
246
+ ; ======================================================
247
+ ; Stage 4: Add Fundamental / 8' drawbar
248
+ ; ======================================================
249
+ rdax ${reg.shaped}, ${param.fundamental}
250
+
251
+ ; ======================================================
252
+ ; Stage 5: Octave Up / 4' drawbar (RMP1, +1 oct)
253
+ ; ======================================================
254
+ ; Save current voice mix (sub + fundamental) to sub_temp
255
+ wra ${mem.sub_temp}, 0.0
256
+
257
+ cho rda, RMP1, REG | COMPC, ${mem.up_buf}
258
+ cho rda, RMP1, 0, ${mem.up_buf} + 1
259
+ wra ${mem.up_temp}, 0.0
260
+ cho rda, RMP1, RPTR2 | COMPC, ${mem.up_buf}
261
+ cho rda, RMP1, RPTR2, ${mem.up_buf} + 1
262
+ cho sof, RMP1, NA | COMPC, 0.0
263
+ cho rda, RMP1, NA, ${mem.up_temp}
264
+
265
+ ; Scale by upper level, add back voice mix
266
+ sof ${param.upper}, 0.0
267
+ rda ${mem.sub_temp}, 1.0
268
+
269
+ ; ======================================================
270
+ ; Stage 6: Rotary Vibrato (SIN0)
271
+ ; ======================================================
272
+ ; Write mixed voices to vibrato delay FIRST (ACC holds voice mix)
273
+ wra ${mem.vib_buf}, 0.0
274
+
275
+ ; Update vibrato rate/depth from CV (safe to clobber ACC now)
276
+ @if pinConnected(rate_cv)
277
+ rdax ${input.rate_cv}, ${param.vibrato_rate} / 511.0
278
+ sof 1.0, ${param.vibrato_rate.min} / 511.0
279
+ wrax SIN0_RATE, 0.0
280
+ @endif
281
+
282
+ @if pinConnected(depth_cv)
283
+ rdax ${input.depth_cv}, ${param.vibrato_depth} / 32767.0
284
+ sof 1.0, ${param.vibrato_depth.min} / 32767.0
285
+ wrax SIN0_RANGE, 0.0
286
+ @endif
287
+
288
+ ; Read with LFO modulation for pitch vibrato
289
+ cho rda, SIN0, SIN | REG | COMPC, ${vib_center}
290
+ cho rda, SIN0, SIN, ${vib_center} + 1
291
+
292
+ ; ======================================================
293
+ ; Stage 7: Tone Filter (2-pole Lowpass)
294
+ ; ======================================================
295
+ ; Save vibrato output, then load tone cutoff from CV
296
+ wrax ${reg.vib_out}, 0.0
297
+
298
+ @cv tone_cv
299
+ wrax ${reg.tone_freq}, 0.0
300
+
301
+ ; Pole 1
302
+ rdax ${reg.vib_out}, 1.0
303
+ rdax ${reg.tone_lp1}, -1.0
304
+ mulx ${reg.tone_freq}
305
+ rdax ${reg.tone_lp1}, 1.0
306
+ wrax ${reg.tone_lp1}, 1.0
307
+
308
+ ; Pole 2
309
+ rdax ${reg.tone_lp2}, -1.0
310
+ mulx ${reg.tone_freq}
311
+ rdax ${reg.tone_lp2}, 1.0
312
+ wrax ${reg.tone_lp2}, 1.0
313
+
314
+ ; ======================================================
315
+ ; Stage 8: Dry/Wet Mix
316
+ ; ======================================================
317
+ @cv mix_cv
318
+ wrax ${reg.mix_reg}, 0.0
319
+
320
+ rdax ${reg.tone_lp2}, 1.0
321
+ rdax ${reg.dry}, -1.0
322
+ mulx ${reg.mix_reg}
323
+ rdax ${reg.dry}, 1.0
324
+ wrax ${output.out}, 0.0
325
+
326
+ @endif
@@ -0,0 +1,300 @@
1
+ ---
2
+ {
3
+ "type": "effects.modulation.phaser",
4
+ "category": "Effects",
5
+ "subcategory": "Modulation",
6
+ "name": "Phaser",
7
+ "description": "Multi-stage phaser with internal SIN1 LFO or external CV control. Produces the classic sweeping notch effect by cascading first-order all-pass filters.",
8
+ "color": "#00ffff",
9
+ "labelTemplate": "${param.lfoSel == 0 ? 'SIN0' : 'SIN1'}",
10
+ "inputs": [
11
+ {
12
+ "id": "audio_input",
13
+ "name": "Audio Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "lfo_speed",
19
+ "name": "LFO Speed",
20
+ "type": "control",
21
+ "required": false,
22
+ "parameter": "rate"
23
+ },
24
+ {
25
+ "id": "lfo_width",
26
+ "name": "LFO Width",
27
+ "type": "control",
28
+ "required": false,
29
+ "parameter": "depth"
30
+ },
31
+ {
32
+ "id": "phase_cv",
33
+ "name": "Phase CV",
34
+ "type": "control",
35
+ "required": false,
36
+ "parameter": "depth"
37
+ }
38
+ ],
39
+ "outputs": [
40
+ {
41
+ "id": "mix_out",
42
+ "name": "Mix Out",
43
+ "type": "audio"
44
+ },
45
+ {
46
+ "id": "wet_out",
47
+ "name": "Wet Out",
48
+ "type": "audio"
49
+ }
50
+ ],
51
+ "parameters": [
52
+ {
53
+ "id": "lfoSel",
54
+ "name": "LFO Selection",
55
+ "type": "select",
56
+ "default": 0,
57
+ "options": [
58
+ { "value": 0, "label": "SIN0" },
59
+ { "value": 1, "label": "SIN1" }
60
+ ],
61
+ "description": "Which SIN oscillator to use (0 or 1)."
62
+ },
63
+ {
64
+ "id": "rate",
65
+ "name": "LFO Rate",
66
+ "type": "number",
67
+ "default": 1.0,
68
+ "min": 0.05,
69
+ "max": 10.0,
70
+ "step": 0.01,
71
+ "conversion": "HZ_TO_LFO_RATE",
72
+ "description": "Speed of the internal SIN1 modulation LFO."
73
+ },
74
+ {
75
+ "id": "depth",
76
+ "name": "Modulation Depth",
77
+ "type": "number",
78
+ "default": 0.25,
79
+ "min": 0.0,
80
+ "max": 1.0,
81
+ "step": 0.01,
82
+ "description": "Depth of the phase sweep."
83
+ },
84
+ {
85
+ "id": "stages",
86
+ "name": "Stages",
87
+ "type": "select",
88
+ "default": 2,
89
+ "options": [
90
+ { "label": "2 Stages", "value": 1 },
91
+ { "label": "4 Stages", "value": 2 },
92
+ { "label": "6 Stages", "value": 3 },
93
+ { "label": "8 Stages", "value": 4 },
94
+ { "label": "10 Stages", "value": 5 }
95
+ ],
96
+ "description": "Number of all-pass stages. More stages create more notches in the spectrum."
97
+ },
98
+ {
99
+ "id": "mode",
100
+ "name": "Control Mode",
101
+ "type": "select",
102
+ "default": 0,
103
+ "options": [
104
+ { "label": "Internal LFO", "value": 0 },
105
+ { "label": "Manual / Phase CV", "value": 1 }
106
+ ],
107
+ "description": "Source of phase modulation."
108
+ }
109
+ ],
110
+ "registers": [
111
+ "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
112
+ "temp", "temp1", "phaseReg", "depthReg", "wet"
113
+ ]
114
+ }
115
+ ---
116
+ ; Phaser
117
+ ; Based on PhaserCADBlock.java
118
+ @if ${param.lfoSel} == 0
119
+ @equals lfoNum SIN0
120
+ @equals lfoRateReg SIN0_RATE
121
+ @else
122
+ @equals lfoNum SIN1
123
+ @equals lfoRateReg SIN1_RATE
124
+ @endif
125
+
126
+
127
+ @section init
128
+ @if isequalto mode 0
129
+ skp run, done_lfo
130
+ wlds ${lfoNum}, ${param.rate}, 32767
131
+ done_lfo:
132
+ @endif
133
+
134
+ @section main
135
+ @if pinConnected(audio_input)
136
+
137
+ ; --- Phase Coefficient Setup ---
138
+ @if isequalto mode 0
139
+ ; Internal LFO Configuration
140
+ @if pinConnected(lfo_speed)
141
+ rdax ${input.lfo_speed}, ${rate} / 511.0
142
+ wrax ${lfoRateReg}, 0.0
143
+ @endif
144
+ @if pinConnected(lfo_width)
145
+ @cv lfo_width
146
+ wrax ${reg.depthReg}, 0.0
147
+ @else
148
+ sof 0.0, ${param.depth}
149
+ wrax ${reg.depthReg}, 0.0
150
+ @endif
151
+
152
+ cho rdal, ${lfoNum}
153
+ sof 0.5, 0.5 ; Map -1..1 to 0..1
154
+ ; Nonlinear sweep approximation
155
+ sof 1.0, -0.5 ; Center at 0.5
156
+ sof 1.999, 0.0 ; Expand to -1..1
157
+ mulx ${reg.depthReg} ; Scale by depth
158
+ sof 0.15, 0.83 ; Map to all-pass stable range [0.83, 0.98]
159
+ wrax ${reg.phaseReg}, 0.0
160
+ @else
161
+ ; External Manual CV
162
+ @cv phase_cv
163
+ sof 0.15, 0.83 ; Map CV [0..1] to [0.83, 0.98]
164
+ wrax ${reg.phaseReg}, 0.0
165
+ @endif
166
+
167
+ ; --- All-pass Filter Chain ---
168
+ ; Use 1/64 attenuation to maintain headroom through the cascade
169
+ rdax ${input.audio_input}, 0.015625
170
+ wrax ${reg.temp}, 0.0 ; Input to first stage
171
+
172
+ ; Stage 1
173
+ rdax ${reg.temp}, 1.0
174
+ wrax ${reg.temp1}, 0.0
175
+ rdax ${reg.p1}, 1.0
176
+ wrax ${reg.temp}, 1.0
177
+ mulx ${reg.phaseReg}
178
+ rdax ${reg.temp1}, 1.0
179
+ wrax ${reg.p1}, -1.0
180
+ mulx ${reg.phaseReg}
181
+
182
+ ; Stage 2
183
+ rdax ${reg.temp}, 1.0
184
+ wrax ${reg.temp1}, 0.0
185
+ rdax ${reg.p2}, 1.0
186
+ wrax ${reg.temp}, 1.0
187
+ mulx ${reg.phaseReg}
188
+ rdax ${reg.temp1}, 1.0
189
+ wrax ${reg.p2}, -1.0
190
+ mulx ${reg.phaseReg}
191
+
192
+ ; Stage 3 & 4
193
+ @if stages >= 2
194
+ rdax ${reg.temp}, 1.0
195
+ wrax ${reg.temp1}, 0.0
196
+ rdax ${reg.p3}, 1.0
197
+ wrax ${reg.temp}, 1.0
198
+ mulx ${reg.phaseReg}
199
+ rdax ${reg.temp1}, 1.0
200
+ wrax ${reg.p3}, -1.0
201
+ mulx ${reg.phaseReg}
202
+
203
+ rdax ${reg.temp}, 1.0
204
+ wrax ${reg.temp1}, 0.0
205
+ rdax ${reg.p4}, 1.0
206
+ wrax ${reg.temp}, 1.0
207
+ mulx ${reg.phaseReg}
208
+ rdax ${reg.temp1}, 1.0
209
+ wrax ${reg.p4}, -1.0
210
+ mulx ${reg.phaseReg}
211
+ @endif
212
+
213
+ ; Stage 5 & 6
214
+ @if stages >= 3
215
+ rdax ${reg.temp}, 1.0
216
+ wrax ${reg.temp1}, 0.0
217
+ rdax ${reg.p5}, 1.0
218
+ wrax ${reg.temp}, 1.0
219
+ mulx ${reg.phaseReg}
220
+ rdax ${reg.temp1}, 1.0
221
+ wrax ${reg.p5}, -1.0
222
+ mulx ${reg.phaseReg}
223
+
224
+ rdax ${reg.temp}, 1.0
225
+ wrax ${reg.temp1}, 0.0
226
+ rdax ${reg.p6}, 1.0
227
+ wrax ${reg.temp}, 1.0
228
+ mulx ${reg.phaseReg}
229
+ rdax ${reg.temp1}, 1.0
230
+ wrax ${reg.p6}, -1.0
231
+ mulx ${reg.phaseReg}
232
+ @endif
233
+
234
+ ; Stage 7 & 8
235
+ @if stages >= 4
236
+ rdax ${reg.temp}, 1.0
237
+ wrax ${reg.temp1}, 0.0
238
+ rdax ${reg.p7}, 1.0
239
+ wrax ${reg.temp}, 1.0
240
+ mulx ${reg.phaseReg}
241
+ rdax ${reg.temp1}, 1.0
242
+ wrax ${reg.p7}, -1.0
243
+ mulx ${reg.phaseReg}
244
+
245
+ rdax ${reg.temp}, 1.0
246
+ wrax ${reg.temp1}, 0.0
247
+ rdax ${reg.p8}, 1.0
248
+ wrax ${reg.temp}, 1.0
249
+ mulx ${reg.phaseReg}
250
+ rdax ${reg.temp1}, 1.0
251
+ wrax ${reg.p8}, -1.0
252
+ mulx ${reg.phaseReg}
253
+ @endif
254
+
255
+ ; Stage 9 & 10
256
+ @if stages >= 5
257
+ rdax ${reg.temp}, 1.0
258
+ wrax ${reg.temp1}, 0.0
259
+ rdax ${reg.p9}, 1.0
260
+ wrax ${reg.temp}, 1.0
261
+ mulx ${reg.phaseReg}
262
+ rdax ${reg.temp1}, 1.0
263
+ wrax ${reg.p9}, -1.0
264
+ mulx ${reg.phaseReg}
265
+
266
+ rdax ${reg.temp}, 1.0
267
+ wrax ${reg.temp1}, 0.0
268
+ rdax ${reg.p10}, 1.0
269
+ wrax ${reg.temp}, 1.0
270
+ mulx ${reg.phaseReg}
271
+ rdax ${reg.temp1}, 1.0
272
+ wrax ${reg.p10}, -1.0
273
+ mulx ${reg.phaseReg}
274
+ @endif
275
+
276
+ ; Final Stage Output Load
277
+ rdax ${reg.temp}, 1.0
278
+
279
+ ; --- Gain Restoration ---
280
+ ; Restores the 1/64 attenuation (6 stages of sof -2.0)
281
+ sof -2.0, 0.0
282
+ sof -2.0, 0.0
283
+ sof -2.0, 0.0
284
+ sof -2.0, 0.0
285
+ sof -2.0, 0.0
286
+ sof -2.0, 0.0
287
+ wrax ${reg.wet}, 1.0 ; Wet signal in wet register and ACC
288
+
289
+ ; --- Output Routing ---
290
+ @if pinConnected(mix_out)
291
+ rdax ${input.audio_input}, 1.0 ; Dry + Wet
292
+ wrax ${output.mix_out}, 0.0
293
+ @endif
294
+
295
+ @if pinConnected(wet_out)
296
+ rdax ${reg.wet}, 1.0
297
+ wrax ${output.wet_out}, 0.0
298
+ @endif
299
+
300
+ @endif
@@ -0,0 +1,80 @@
1
+ ---
2
+ {
3
+ "type": "effects.pitch.octave_up_down",
4
+ "name": "Octave Up & Down",
5
+ "category": "Effects",
6
+ "subcategory": "Pitch",
7
+ "description": "Fixed pitch shifter with both Octave Up and Octave Down outputs.",
8
+ "color": "#fcba03",
9
+ "inputs": [
10
+ {
11
+ "id": "in",
12
+ "name": "Input",
13
+ "type": "audio",
14
+ "required": true
15
+ }
16
+ ],
17
+ "outputs": [
18
+ {
19
+ "id": "octave_down",
20
+ "name": "Octave Down",
21
+ "type": "audio"
22
+ },
23
+ {
24
+ "id": "octave_up",
25
+ "name": "Octave Up",
26
+ "type": "audio"
27
+ }
28
+ ],
29
+ "memories": [
30
+ {
31
+ "id": "delayl",
32
+ "size": "bufferSize"
33
+ },
34
+ {
35
+ "id": "temp",
36
+ "size": 1
37
+ }
38
+ ],
39
+ "registers": [],
40
+ "parameters": []
41
+ }
42
+ ---
43
+ @section header
44
+ @equals bufferSize 4096
45
+
46
+ @section init
47
+ ; Octave Up (s = 2; rate = (2-1)*16384 = 16384)
48
+ ; Octave Down (s = 0.5; rate = (0.5-1)*16384 = -8192)
49
+ skp run, done_init
50
+ wldr 0, -8192, ${bufferSize}
51
+ wldr 1, 16384, ${bufferSize}
52
+ done_init:
53
+
54
+ @section main
55
+ rdax ${input.in}, 1.0
56
+ wra ${mem.delayl}, 0.0
57
+
58
+ @if pinConnected(octave_down)
59
+ ; Perform Octave Down (RMP0)
60
+ cho rda, RMP0, REG | COMPC, ${mem.delayl}
61
+ cho rda, RMP0, 0, ${mem.delayl} + 1
62
+ wra ${mem.temp}, 0.0
63
+ cho rda, RMP0, RPTR2 | COMPC, ${mem.delayl}
64
+ cho rda, RMP0, RPTR2, ${mem.delayl} + 1
65
+ cho sof, RMP0, NA | COMPC, 0.0
66
+ cho rda, RMP0, NA, ${mem.temp}
67
+ wrax ${output.octave_down}, 0.0
68
+ @endif
69
+
70
+ @if pinConnected(octave_up)
71
+ ; Perform Octave Up (RMP1)
72
+ cho rda, RMP1, REG | COMPC, ${mem.delayl}
73
+ cho rda, RMP1, 0, ${mem.delayl} + 1
74
+ wra ${mem.temp}, 0.0
75
+ cho rda, RMP1, RPTR2 | COMPC, ${mem.delayl}
76
+ cho rda, RMP1, RPTR2, ${mem.delayl} + 1
77
+ cho sof, RMP1, NA | COMPC, 0.0
78
+ cho rda, RMP1, NA, ${mem.temp}
79
+ wrax ${output.octave_up}, 0.0
80
+ @endif