@audiofab-io/fv1-core 0.2.2 → 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.
- package/blocks/ATL_DEVELOPER_REFERENCE.md +156 -0
- package/blocks/control/constant.atl +36 -0
- package/blocks/control/entropy_lfo.atl +74 -0
- package/blocks/control/envelope.atl +121 -0
- package/blocks/control/invert.atl +33 -0
- package/blocks/control/pot.atl +150 -0
- package/blocks/control/power.atl +77 -0
- package/blocks/control/ramp_lfo.atl +122 -0
- package/blocks/control/scale_offset.atl +84 -0
- package/blocks/control/sincos_lfo.atl +126 -0
- package/blocks/control/smoother.atl +48 -0
- package/blocks/control/tremolizer.atl +55 -0
- package/blocks/effects/delay/micro_stutter.atl +77 -0
- package/blocks/effects/delay/mn3011.atl +281 -0
- package/blocks/effects/delay/simple_delay.atl +96 -0
- package/blocks/effects/delay/triple_tap_delay.atl +176 -0
- package/blocks/effects/lo-fi/bit_mangler.atl +74 -0
- package/blocks/effects/lo-fi/chiptune.atl +311 -0
- package/blocks/effects/lo-fi/tape_degrade.atl +181 -0
- package/blocks/effects/modulation/chorus.atl +141 -0
- package/blocks/effects/modulation/chorus_4voice.atl +188 -0
- package/blocks/effects/modulation/flanger.atl +184 -0
- package/blocks/effects/modulation/guitar_synth.atl +350 -0
- package/blocks/effects/modulation/harmonic_trem.atl +129 -0
- package/blocks/effects/modulation/organ_synth.atl +326 -0
- package/blocks/effects/modulation/phaser.atl +300 -0
- package/blocks/effects/pitch/octave_up_down.atl +80 -0
- package/blocks/effects/pitch/pitch_offset.atl +149 -0
- package/blocks/effects/pitch/pitch_offset_dual.atl +197 -0
- package/blocks/effects/pitch/pitch_shift.atl +115 -0
- package/blocks/effects/pitch/sub_octave.atl +100 -0
- package/blocks/effects/reverb/ducking_reverb.atl +145 -0
- package/blocks/effects/reverb/min_reverb.atl +132 -0
- package/blocks/effects/reverb/plate_reverb.atl +344 -0
- package/blocks/effects/reverb/room_reverb.atl +293 -0
- package/blocks/effects/reverb/smear.atl +90 -0
- package/blocks/effects/reverb/spring_reverb.atl +353 -0
- package/blocks/filter/1p_high_pass.atl +63 -0
- package/blocks/filter/1p_low_pass.atl +59 -0
- package/blocks/filter/auto_wah.atl +207 -0
- package/blocks/filter/bbd_loss.atl +79 -0
- package/blocks/filter/shelving_high_pass.atl +76 -0
- package/blocks/filter/shelving_low_pass.atl +76 -0
- package/blocks/filter/svf_2p.atl +116 -0
- package/blocks/gain_mix/crossfade.atl +93 -0
- package/blocks/gain_mix/crossfade2.atl +86 -0
- package/blocks/gain_mix/crossfade3.atl +71 -0
- package/blocks/gain_mix/gainboost.atl +54 -0
- package/blocks/gain_mix/mixer2.atl +76 -0
- package/blocks/gain_mix/mixer3.atl +109 -0
- package/blocks/gain_mix/mixer4.atl +152 -0
- package/blocks/gain_mix/volume.atl +51 -0
- package/blocks/io/adc.atl +53 -0
- package/blocks/io/dac.atl +61 -0
- package/blocks/other/stickynote.atl +24 -0
- package/blocks/other/tone_gen_adjustable.atl +137 -0
- package/blocks/other/tone_gen_fixed.atl +109 -0
- package/dist/blockDiagram/blocks/BlockDirectoryLoader.d.ts +13 -0
- package/dist/blockDiagram/blocks/BlockDirectoryLoader.d.ts.map +1 -0
- package/dist/blockDiagram/blocks/BlockDirectoryLoader.js +44 -0
- package/dist/blockDiagram/blocks/BlockDirectoryLoader.js.map +1 -0
- package/dist/blockDiagram/blocks/BlockRegistry.d.ts +48 -0
- package/dist/blockDiagram/blocks/BlockRegistry.d.ts.map +1 -0
- package/dist/blockDiagram/blocks/BlockRegistry.js +109 -0
- package/dist/blockDiagram/blocks/BlockRegistry.js.map +1 -0
- package/dist/blockDiagram/blocks/TemplateBlock.d.ts +20 -0
- package/dist/blockDiagram/blocks/TemplateBlock.d.ts.map +1 -0
- package/dist/blockDiagram/blocks/TemplateBlock.js +82 -0
- package/dist/blockDiagram/blocks/TemplateBlock.js.map +1 -0
- package/dist/blockDiagram/blocks/base/BaseBlock.d.ts +248 -0
- package/dist/blockDiagram/blocks/base/BaseBlock.d.ts.map +1 -0
- package/dist/blockDiagram/blocks/base/BaseBlock.js +402 -0
- package/dist/blockDiagram/blocks/base/BaseBlock.js.map +1 -0
- package/dist/blockDiagram/builtinBlocks.d.ts +9 -0
- package/dist/blockDiagram/builtinBlocks.d.ts.map +1 -0
- package/dist/blockDiagram/builtinBlocks.js +4912 -0
- package/dist/blockDiagram/builtinBlocks.js.map +1 -0
- package/dist/blockDiagram/compiler/BlockTemplate.d.ts +37 -0
- package/dist/blockDiagram/compiler/BlockTemplate.d.ts.map +1 -0
- package/dist/blockDiagram/compiler/BlockTemplate.js +860 -0
- package/dist/blockDiagram/compiler/BlockTemplate.js.map +1 -0
- package/dist/blockDiagram/compiler/CodeOptimizer.d.ts +75 -0
- package/dist/blockDiagram/compiler/CodeOptimizer.d.ts.map +1 -0
- package/dist/blockDiagram/compiler/CodeOptimizer.js +443 -0
- package/dist/blockDiagram/compiler/CodeOptimizer.js.map +1 -0
- package/dist/blockDiagram/compiler/GraphCompiler.d.ts +63 -0
- package/dist/blockDiagram/compiler/GraphCompiler.d.ts.map +1 -0
- package/dist/blockDiagram/compiler/GraphCompiler.js +656 -0
- package/dist/blockDiagram/compiler/GraphCompiler.js.map +1 -0
- package/dist/blockDiagram/compiler/TopologicalSort.d.ts +63 -0
- package/dist/blockDiagram/compiler/TopologicalSort.d.ts.map +1 -0
- package/dist/blockDiagram/compiler/TopologicalSort.js +268 -0
- package/dist/blockDiagram/compiler/TopologicalSort.js.map +1 -0
- package/dist/blockDiagram/index.d.ts +30 -0
- package/dist/blockDiagram/index.d.ts.map +1 -0
- package/dist/blockDiagram/index.js +29 -0
- package/dist/blockDiagram/index.js.map +1 -0
- package/dist/blockDiagram/types/Block.d.ts +178 -0
- package/dist/blockDiagram/types/Block.d.ts.map +1 -0
- package/dist/blockDiagram/types/Block.js +5 -0
- package/dist/blockDiagram/types/Block.js.map +1 -0
- package/dist/blockDiagram/types/CodeGenContext.d.ts +235 -0
- package/dist/blockDiagram/types/CodeGenContext.d.ts.map +1 -0
- package/dist/blockDiagram/types/CodeGenContext.js +554 -0
- package/dist/blockDiagram/types/CodeGenContext.js.map +1 -0
- package/dist/blockDiagram/types/Connection.d.ts +17 -0
- package/dist/blockDiagram/types/Connection.d.ts.map +1 -0
- package/dist/blockDiagram/types/Connection.js +5 -0
- package/dist/blockDiagram/types/Connection.js.map +1 -0
- package/dist/blockDiagram/types/Graph.d.ts +28 -0
- package/dist/blockDiagram/types/Graph.d.ts.map +1 -0
- package/dist/blockDiagram/types/Graph.js +24 -0
- package/dist/blockDiagram/types/Graph.js.map +1 -0
- package/dist/blockDiagram/types/IR.d.ts +79 -0
- package/dist/blockDiagram/types/IR.d.ts.map +1 -0
- package/dist/blockDiagram/types/IR.js +6 -0
- package/dist/blockDiagram/types/IR.js.map +1 -0
- package/dist/blockDiagram/utils/SpinCADConverter.d.ts +17 -0
- package/dist/blockDiagram/utils/SpinCADConverter.d.ts.map +1 -0
- package/dist/blockDiagram/utils/SpinCADConverter.js +307 -0
- package/dist/blockDiagram/utils/SpinCADConverter.js.map +1 -0
- package/dist/effect/compileEffect.d.ts +51 -0
- package/dist/effect/compileEffect.d.ts.map +1 -0
- package/dist/effect/compileEffect.js +133 -0
- package/dist/effect/compileEffect.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/simulator/FV1Simulator.d.ts.map +1 -1
- package/dist/simulator/FV1Simulator.js +7 -4
- package/dist/simulator/FV1Simulator.js.map +1 -1
- 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
|