@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,149 @@
1
+ ---
2
+ {
3
+ "type": "effects.pitch.pitch_offset",
4
+ "name": "Pitch Offset (Hilbert)",
5
+ "category": "Effects",
6
+ "subcategory": "Pitch",
7
+ "description": "Bipolar frequency shift (+/-). Neutral at 12 o'clock, turning down lowers pitch, turning up raises pitch.",
8
+ "color": "#fcba03",
9
+ "inputs": [
10
+ {
11
+ "id": "in",
12
+ "name": "Audio Input",
13
+ "type": "audio",
14
+ "required": true
15
+ },
16
+ {
17
+ "id": "shift_ctrl",
18
+ "name": "Shift CV",
19
+ "type": "control",
20
+ "required": false,
21
+ "parameter": "shiftValue"
22
+ }
23
+ ],
24
+ "outputs": [
25
+ {
26
+ "id": "out",
27
+ "name": "Output",
28
+ "type": "audio"
29
+ }
30
+ ],
31
+ "parameters": [
32
+ {
33
+ "id": "shiftRange",
34
+ "name": "Shift Range (Hz)",
35
+ "type": "number",
36
+ "default": 600,
37
+ "min": 1,
38
+ "max": 2000,
39
+ "conversion": "HZ_TO_HILBERT_SHIFT",
40
+ "description": "The total frequency range covered by the Shift control (e.g. 600 means +/- 300Hz)."
41
+ },
42
+ {
43
+ "id": "shiftValue",
44
+ "name": "Shift",
45
+ "type": "number",
46
+ "default": 0.5,
47
+ "min": 0.0,
48
+ "max": 1.0,
49
+ "step": 0.01,
50
+ "description": "Manual control for pitch shift. 0.5 is neutral (no shift)."
51
+ }
52
+ ],
53
+ "registers": [
54
+ "sigs",
55
+ "sigc",
56
+ "lpf",
57
+ "hpf",
58
+ "sigfil",
59
+ "sinosc",
60
+ "cososc",
61
+ "temp",
62
+ "shift_amount",
63
+ "potfil"
64
+ ],
65
+ "memories": [
66
+ { "id": "ap1", "size": 2 },
67
+ { "id": "ap2", "size": 2 },
68
+ { "id": "ap3", "size": 2 },
69
+ { "id": "ap4", "size": 2 },
70
+ { "id": "ap5", "size": 2 },
71
+ { "id": "ap6", "size": 2 }
72
+ ]
73
+ }
74
+ ---
75
+ @section header
76
+
77
+ @section init
78
+ ; Initialize oscillator (cosine = 1.0)
79
+ skp run, done_init
80
+ or $7fffff
81
+ wrax ${reg.cososc}, 0.0
82
+ done_init:
83
+
84
+ @section main
85
+ ; 1. Process CV and smoothing
86
+ @cv shift_ctrl
87
+ ; ACC = Shift position (0..1, defaults to 0.5)
88
+ rdfx ${reg.potfil}, 0.001
89
+ wrlx ${reg.potfil}, -1.0
90
+ ; Map [0..1] to [Range/2 .. -Range/2]
91
+ ; Bipolar: (0.5 - shiftValue) * Range
92
+ sof -1.0, 0.5
93
+ sof ${shiftRange}, 0.0 ; Substitutes converted HZ_TO_HILBERT_SHIFT value
94
+ wrax ${reg.shift_amount}, 0.0
95
+
96
+ ; 2. Audio input filtering (300Hz HPF, 3kHz LPF)
97
+ rdax ${input.in}, 1.0
98
+ rdfx ${reg.hpf}, 0.04
99
+ wrhx ${reg.hpf}, -1.0
100
+ rdfx ${reg.lpf}, 0.4
101
+ wrlx ${reg.lpf}, -1.0
102
+ wrax ${reg.sigfil}, 0.0039 ; Attenuate to avoid clipping in Hilbert chain
103
+
104
+ ; 3. All-pass phase shifter bank (Sine path)
105
+ rda ${mem.ap1} + 1, 0.995 ; 44Hz
106
+ wrap ${mem.ap1}, -0.995
107
+ rda ${mem.ap2} + 1, 0.937 ; 488Hz
108
+ wrap ${mem.ap2}, -0.937
109
+ rda ${mem.ap3} + 1, 0.61 ; 3531Hz
110
+ wrap ${mem.ap3}, -0.61
111
+ wrax ${reg.sigs}, 0.0
112
+
113
+ ; 4. All-pass phase shifter bank (Cosine path)
114
+ rdax ${reg.sigfil}, 0.0039 ; Match Sine path attenuation
115
+ rda ${mem.ap4} + 1, 0.978 ; 178Hz
116
+ wrap ${mem.ap4}, -0.978
117
+ rda ${mem.ap5} + 1, 0.84 ; 1289Hz
118
+ wrap ${mem.ap5}, -0.84
119
+ rda ${mem.ap6} + 1, 0.0
120
+ wrap ${mem.ap6}, 0.0
121
+ wrax ${reg.sigc}, 0.0
122
+
123
+ ; 5. Update Oscillator (Quadrature oscillator)
124
+ rdax ${reg.cososc}, 1.0
125
+ mulx ${reg.shift_amount}
126
+ rdax ${reg.sinosc}, 1.0
127
+ wrax ${reg.sinosc}, -1.0
128
+ mulx ${reg.shift_amount}
129
+ rdax ${reg.cososc}, 1.0
130
+ wrax ${reg.cososc}, 0.0
131
+
132
+ ; 6. Modulation and Summing (Hilbert - SpinCAD pattern)
133
+ ; Sum = -2 * (in_c * cos + in_s * sin) -> Frequency DOWN if rate > 0
134
+ rdax ${reg.sigc}, -2.0
135
+ mulx ${reg.cososc}
136
+ wrax ${reg.temp}, 0.0
137
+ rdax ${reg.sigs}, -2.0
138
+ mulx ${reg.sinosc}
139
+ rdax ${reg.temp}, 1.0
140
+
141
+ ; Scale back up to recovery signal level
142
+ sof -2.0, 0.0
143
+ sof -2.0, 0.0
144
+ sof -2.0, 0.0
145
+ sof -2.0, 0.0
146
+ sof -2.0, 0.0
147
+ sof -2.0, 0.0
148
+ sof -2.0, 0.0
149
+ wrax ${output.out}, 0.0
@@ -0,0 +1,197 @@
1
+ ---
2
+ {
3
+ "type": "effects.pitch.pitch_offset_dual",
4
+ "name": "Dual Pitch Offset (Hilbert)",
5
+ "category": "Effects",
6
+ "subcategory": "Pitch",
7
+ "description": "Two independent bipolar frequency offsets mixed to a mono output.",
8
+ "color": "#fcba03",
9
+ "inputs": [
10
+ {
11
+ "id": "in",
12
+ "name": "Audio Input",
13
+ "type": "audio",
14
+ "required": true
15
+ },
16
+ {
17
+ "id": "shift1_ctrl",
18
+ "name": "Shift 1 CV",
19
+ "type": "control",
20
+ "required": false,
21
+ "parameter": "shiftValue1"
22
+ },
23
+ {
24
+ "id": "shift2_ctrl",
25
+ "name": "Shift 2 CV",
26
+ "type": "control",
27
+ "required": false,
28
+ "parameter": "shiftValue2"
29
+ }
30
+ ],
31
+ "outputs": [
32
+ {
33
+ "id": "out",
34
+ "name": "Output",
35
+ "type": "audio"
36
+ }
37
+ ],
38
+ "parameters": [
39
+ {
40
+ "id": "shiftRange",
41
+ "name": "Shift Range (Hz)",
42
+ "type": "number",
43
+ "default": 600,
44
+ "min": 1,
45
+ "max": 2000,
46
+ "conversion": "HZ_TO_HILBERT_SHIFT",
47
+ "description": "Total frequency range for both controls."
48
+ },
49
+ {
50
+ "id": "shiftValue1",
51
+ "name": "Shift 1",
52
+ "type": "number",
53
+ "default": 0.5,
54
+ "min": 0.0,
55
+ "max": 1.0,
56
+ "step": 0.01,
57
+ "description": "Bipolar control for shift 1."
58
+ },
59
+ {
60
+ "id": "shiftValue2",
61
+ "name": "Shift 2",
62
+ "type": "number",
63
+ "default": 0.5,
64
+ "min": 0.0,
65
+ "max": 1.0,
66
+ "step": 0.01,
67
+ "description": "Bipolar control for shift 2."
68
+ }
69
+ ],
70
+ "registers": [
71
+ "sigs",
72
+ "sigc",
73
+ "lpf",
74
+ "hpf",
75
+ "sigfil",
76
+ "sinosc1",
77
+ "cososc1",
78
+ "sinosc2",
79
+ "cososc2",
80
+ "temp1",
81
+ "temp2",
82
+ "shift1_amt",
83
+ "shift2_amt",
84
+ "potfil1",
85
+ "potfil2"
86
+ ],
87
+ "memories": [
88
+ { "id": "ap1", "size": 2 },
89
+ { "id": "ap2", "size": 2 },
90
+ { "id": "ap3", "size": 2 },
91
+ { "id": "ap4", "size": 2 },
92
+ { "id": "ap5", "size": 2 },
93
+ { "id": "ap6", "size": 2 }
94
+ ]
95
+ }
96
+ ---
97
+ @section header
98
+
99
+ @section init
100
+ ; Initialize oscillators (cosine = 1.0)
101
+ skp run, done_init
102
+ or $7fffff
103
+ wrax ${reg.cososc1}, 1.0
104
+ wrax ${reg.cososc2}, 0.0
105
+ done_init:
106
+
107
+ @section main
108
+ ; 1. Process CVs and smoothing
109
+ @cv shift1_ctrl
110
+ rdfx ${reg.potfil1}, 0.001
111
+ wrlx ${reg.potfil1}, -1.0
112
+ ; Bipolar mapping: ACC = (0.5 - shift1) * range
113
+ sof -1.0, 0.5
114
+ sof ${shiftRange}, 0.0
115
+ wrax ${reg.shift1_amt}, 0.0
116
+
117
+ @cv shift2_ctrl
118
+ rdfx ${reg.potfil2}, 0.001
119
+ wrlx ${reg.potfil2}, -1.0
120
+ ; Bipolar mapping: ACC = (0.5 - shift2) * range
121
+ sof -1.0, 0.5
122
+ sof ${shiftRange}, 0.0
123
+ wrax ${reg.shift2_amt}, 0.0
124
+
125
+ ; 2. Audio input filtering
126
+ rdax ${input.in}, 1.0
127
+ rdfx ${reg.hpf}, 0.04
128
+ wrhx ${reg.hpf}, -1.0
129
+ rdfx ${reg.lpf}, 0.4
130
+ wrlx ${reg.lpf}, -1.0
131
+ wrax ${reg.sigfil}, 0.0039
132
+
133
+ ; 3. Hilbert phase shifter (Shared)
134
+ ; Sine path
135
+ rda ${mem.ap1} + 1, 0.995 ; 44Hz
136
+ wrap ${mem.ap1}, -0.995
137
+ rda ${mem.ap2} + 1, 0.937 ; 488Hz
138
+ wrap ${mem.ap2}, -0.937
139
+ rda ${mem.ap3} + 1, 0.61 ; 3531Hz
140
+ wrap ${mem.ap3}, -0.61
141
+ wrax ${reg.sigs}, 0.0
142
+
143
+ ; Cosine path
144
+ rdax ${reg.sigfil}, 0.0039
145
+ rda ${mem.ap4} + 1, 0.978 ; 178Hz
146
+ wrap ${mem.ap4}, -0.978
147
+ rda ${mem.ap5} + 1, 0.84 ; 1289Hz
148
+ wrap ${mem.ap5}, -0.84
149
+ rda ${mem.ap6} + 1, 0.0
150
+ wrap ${mem.ap6}, 0.0
151
+ wrax ${reg.sigc}, 0.0
152
+
153
+ ; 4. Oscillator 1 update
154
+ rdax ${reg.cososc1}, 1.0
155
+ mulx ${reg.shift1_amt}
156
+ rdax ${reg.sinosc1}, 1.0
157
+ wrax ${reg.sinosc1}, -1.0
158
+ mulx ${reg.shift1_amt}
159
+ rdax ${reg.cososc1}, 1.0
160
+ wrax ${reg.cososc1}, 0.0
161
+
162
+ ; 5. Pitch shift 1 calculation
163
+ rdax ${reg.sigc}, -2.0
164
+ mulx ${reg.cososc1}
165
+ wrax ${reg.temp1}, 0.0
166
+ rdax ${reg.sigs}, -2.0
167
+ mulx ${reg.sinosc1}
168
+ rdax ${reg.temp1}, 1.0
169
+ wrax ${reg.temp1}, 0.0
170
+
171
+ ; 6. Oscillator 2 update
172
+ rdax ${reg.cososc2}, 1.0
173
+ mulx ${reg.shift2_amt}
174
+ rdax ${reg.sinosc2}, 1.0
175
+ wrax ${reg.sinosc2}, -1.0
176
+ mulx ${reg.shift2_amt}
177
+ rdax ${reg.cososc2}, 1.0
178
+ wrax ${reg.cososc2}, 0.0
179
+
180
+ ; 7. Pitch shift 2 calculation
181
+ rdax ${reg.sigc}, -2.0
182
+ mulx ${reg.cososc2}
183
+ wrax ${reg.temp2}, 0.0
184
+ rdax ${reg.sigs}, -2.0
185
+ mulx ${reg.sinosc2}
186
+ rdax ${reg.temp2}, 1.0
187
+
188
+ ; 8. Sum results and scale up
189
+ rdax ${reg.temp1}, 0.5 ; Mix
190
+ sof -2.0, 0.0
191
+ sof -2.0, 0.0
192
+ sof -2.0, 0.0
193
+ sof -2.0, 0.0
194
+ sof -2.0, 0.0
195
+ sof -2.0, 0.0
196
+ sof -2.0, 0.0
197
+ wrax ${output.out}, 0.0
@@ -0,0 +1,115 @@
1
+ ---
2
+ {
3
+ "type": "effects.pitch.pitch_shift",
4
+ "name": "Pitch Shift",
5
+ "category": "Effects",
6
+ "subcategory": "Pitch",
7
+ "description": "Adjustable pitch shifter using Ramp LFOs.",
8
+ "color": "#fcba03",
9
+ "width": 180,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "pitch_ctrl",
19
+ "name": "Pitch CV",
20
+ "type": "control",
21
+ "required": false,
22
+ "parameter": "semitones"
23
+ }
24
+ ],
25
+ "outputs": [
26
+ {
27
+ "id": "out",
28
+ "name": "Output",
29
+ "type": "audio"
30
+ }
31
+ ],
32
+ "parameters": [
33
+ {
34
+ "id": "semitones",
35
+ "name": "Pitch (Semitones)",
36
+ "type": "number",
37
+ "default": 12,
38
+ "min": -24,
39
+ "max": 24,
40
+ "step": 0.1,
41
+ "conversion": "SEMITONES_TO_RATE",
42
+ "description": "Base pitch shift in semitones. If Pitch CV is connected, this acts as the maximum shift range."
43
+ },
44
+ {
45
+ "id": "lfoWidth",
46
+ "name": "Buffer Size",
47
+ "type": "select",
48
+ "default": 4096,
49
+ "options": [
50
+ { "label": "4096 (Smooth)", "value": 4096 },
51
+ { "label": "2048", "value": 2048 },
52
+ { "label": "1024", "value": 1024 },
53
+ { "label": "512 (Lo-fi)", "value": 512 }
54
+ ],
55
+ "description": "Size of the pitch shift buffer. Larger values are smoother but add more latency."
56
+ },
57
+ {
58
+ "id": "lfoSel",
59
+ "name": "LFO Slot",
60
+ "type": "select",
61
+ "default": 0,
62
+ "options": [
63
+ { "label": "Ramp 0", "value": 0 },
64
+ { "label": "Ramp 1", "value": 1 }
65
+ ]
66
+ }
67
+ ],
68
+ "memories": [
69
+ {
70
+ "id": "buffer",
71
+ "size": "lfoWidth"
72
+ },
73
+ {
74
+ "id": "temp",
75
+ "size": 1
76
+ }
77
+ ],
78
+ "registers": []
79
+ }
80
+ ---
81
+ @section header
82
+ @if lfoSel == 0
83
+ @equals lfo RMP0
84
+ @equals lfo_rate RMP0_RATE
85
+ @else
86
+ @equals lfo RMP1
87
+ @equals lfo_rate RMP1_RATE
88
+ @endif
89
+
90
+ @section init
91
+ ; Initialize Ramp LFO
92
+ skp run, done_init
93
+ wldr ${lfoSel}, ${semitones}, ${lfoWidth}
94
+ done_init:
95
+
96
+ @section main
97
+ ; Write input to delay buffer
98
+ rdax ${input.in}, 1.0
99
+ wra ${mem.buffer}, 0.0
100
+
101
+ ; Update pitch shift rate via CV
102
+ @cv pitch_ctrl
103
+ wrax ${lfo_rate}, 0.0
104
+
105
+ ; Perform pitch shift (dual-tap for crossfading)
106
+ cho rda, ${lfo}, REG | COMPC, ${mem.buffer}
107
+ cho rda, ${lfo}, 0, ${mem.buffer} + 1
108
+ wra ${mem.temp}, 0.0
109
+
110
+ cho rda, ${lfo}, RPTR2 | COMPC, ${mem.buffer}
111
+ cho rda, ${lfo}, RPTR2, ${mem.buffer} + 1
112
+ cho sof, ${lfo}, NA | COMPC, 0.0
113
+ cho rda, ${lfo}, NA, ${mem.temp}
114
+
115
+ wrax ${output.out}, 0.0
@@ -0,0 +1,100 @@
1
+ ---
2
+ {
3
+ "type": "fx.sub_octave",
4
+ "name": "Sub-Octave Synth",
5
+ "category": "Effects",
6
+ "subcategory": "Pitch",
7
+ "description": "Clean -1 octave generator with an integrated lowpass filter to remove pitch-shifting artifacts.",
8
+ "color": "#fcba03",
9
+ "width": 180,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Input",
14
+ "type": "audio",
15
+ "required": true
16
+ }
17
+ ],
18
+ "outputs": [
19
+ {
20
+ "id": "out",
21
+ "name": "Output",
22
+ "type": "audio"
23
+ }
24
+ ],
25
+ "parameters": [
26
+ {
27
+ "id": "sub_level",
28
+ "name": "Sub Level",
29
+ "type": "number",
30
+ "default": 1.0,
31
+ "min": 0.0,
32
+ "max": 1.5,
33
+ "step": 0.05
34
+ },
35
+ {
36
+ "id": "filter_freq",
37
+ "name": "Filter Frequency",
38
+ "type": "number",
39
+ "default": 250,
40
+ "min": 80,
41
+ "max": 800,
42
+ "step": 10,
43
+ "conversion": "SVFFREQ",
44
+ "description": "Frequency cutoff to remove digital fuzz from the pitch shifted signal."
45
+ }
46
+ ],
47
+ "memories": [
48
+ {
49
+ "id": "buffer",
50
+ "size": 4096
51
+ },
52
+ {
53
+ "id": "temp",
54
+ "size": 1
55
+ }
56
+ ],
57
+ "registers": [
58
+ "lps",
59
+ "lp2"
60
+ ]
61
+ }
62
+ ---
63
+ @section init
64
+ ; Initialize Ramp LFO for EXACTLY -1 Octave (rate -8192 = 0.5x speed)
65
+ skp run, init_sub
66
+ wldr RMP0, -8192, 4096
67
+ init_sub:
68
+
69
+ @section main
70
+ ; Write input to delay buffer
71
+ rdax ${input.in}, 1.0
72
+ wra ${mem.buffer}, 0.0
73
+
74
+ ; Read Pitch -1 Octave
75
+ cho rda, RMP0, REG | COMPC, ${mem.buffer}
76
+ cho rda, RMP0, 0, ${mem.buffer} + 1
77
+ wra ${mem.temp}, 0.0
78
+ cho rda, RMP0, RPTR2 | COMPC, ${mem.buffer}
79
+ cho rda, RMP0, RPTR2, ${mem.buffer} + 1
80
+ cho sof, RMP0, NA | COMPC, 0.0
81
+ cho rda, RMP0, NA, ${mem.temp}
82
+
83
+ ; ACC now contains the raw -1 octave signal
84
+ ; Apply 2-Pole Lowpass filter to clean it up into a synth sine wave
85
+
86
+ ; Pole 1
87
+ rdax ${reg.lps}, -1.0
88
+ sof ${param.filter_freq}, 0.0
89
+ rdax ${reg.lps}, 1.0
90
+ wrax ${reg.lps}, 1.0
91
+
92
+ ; Pole 2
93
+ rdax ${reg.lp2}, -1.0
94
+ sof ${param.filter_freq}, 0.0
95
+ rdax ${reg.lp2}, 1.0
96
+ wrax ${reg.lp2}, 1.0
97
+
98
+ ; Gain
99
+ sof ${param.sub_level}, 0.0
100
+ wrax ${output.out}, 0.0
@@ -0,0 +1,145 @@
1
+ ---
2
+ {
3
+ "type": "fx.ducking_reverb",
4
+ "name": "Ducking Reverb",
5
+ "category": "Effects",
6
+ "subcategory": "Reverb",
7
+ "description": "Reverb that automatically ducks in volume while you are playing.",
8
+ "color": "#7100fc",
9
+ "width": 180,
10
+ "inputs": [
11
+ {
12
+ "id": "in",
13
+ "name": "Audio Input",
14
+ "type": "audio",
15
+ "required": true
16
+ },
17
+ {
18
+ "id": "decay_cv",
19
+ "name": "Decay",
20
+ "type": "control",
21
+ "required": false,
22
+ "parameter": "decay"
23
+ },
24
+ {
25
+ "id": "duck_sens_cv",
26
+ "name": "Sensitivity",
27
+ "type": "control",
28
+ "required": false,
29
+ "parameter": "duck_sens"
30
+ }
31
+ ],
32
+ "outputs": [
33
+ {
34
+ "id": "out",
35
+ "name": "Audio Output",
36
+ "type": "audio"
37
+ }
38
+ ],
39
+ "parameters": [
40
+ {
41
+ "id": "decay",
42
+ "name": "Reverb Decay",
43
+ "type": "number",
44
+ "default": 0.85,
45
+ "min": 0,
46
+ "max": 0.99,
47
+ "step": 0.01,
48
+ "description": "Length of the reverb tail."
49
+ },
50
+ {
51
+ "id": "duck_sens",
52
+ "name": "Ducking Sensitivity",
53
+ "type": "number",
54
+ "default": 2.0,
55
+ "min": 0.0,
56
+ "max": 10.0,
57
+ "step": 0.1,
58
+ "description": "How hard the reverb ducks when you play."
59
+ }
60
+ ],
61
+ "memories": [
62
+ { "id": "ap1", "size": 142 },
63
+ { "id": "ap2", "size": 379 },
64
+ { "id": "ap3", "size": 842 },
65
+ { "id": "ap4", "size": 1111 },
66
+ { "id": "del1", "size": 4012 },
67
+ { "id": "del2", "size": 5211 }
68
+ ],
69
+ "registers": [
70
+ "env",
71
+ "gain",
72
+ "apout",
73
+ "duck_sens_val",
74
+ "decay_val"
75
+ ]
76
+ }
77
+ ---
78
+ @section main
79
+ @equals kap 0.5
80
+
81
+ ; Evaluate CVs
82
+ @cv duck_sens_cv
83
+ wrax ${reg.duck_sens_val}, 0.0
84
+ @cv decay_cv
85
+ wrax ${reg.decay_val}, 0.0
86
+
87
+ ; 1. Envelope Follower (Fast Attack, Slow Release)
88
+ rdax ${input.in}, 1.0
89
+ absa
90
+ rdax ${reg.env}, -1.0 ; ACC = |IN| - ENV
91
+ skp gez, attack
92
+ ; Release path
93
+ sof 0.005, 0.0 ; Slow release
94
+ skp run, update_env
95
+ attack:
96
+ sof 0.5, 0.0 ; Fast attack
97
+ update_env:
98
+ rdax ${reg.env}, 1.0 ; ACC = Delta + ENV
99
+ wrax ${reg.env}, 1.0 ; Update ENV register, keeping ENV in ACC
100
+
101
+ ; 2. Calculate Ducking Gain (Gain = 1.0 - Sens * ENV)
102
+ ; Limit Gain from dropping below 0
103
+ rdax ${reg.env}, -0.25 ; ACC = -ENV/4 (Scale down env impact to allow high sens numbers)
104
+ mulx ${reg.duck_sens_val} ; ACC = -ENV/4 * Sens
105
+ sof 1.0, 1.0 ; ACC = 1.0 - (ENV/4 * Sens)
106
+
107
+ ; Clamp Gain to positive values
108
+ skp gez, no_clamp
109
+ sof 0.0, 0.0
110
+ no_clamp:
111
+ wrax ${reg.gain}, 0.0 ; Save final Ducking Gain
112
+
113
+ ; 3. Reverb Input scaling (Wet signal only)
114
+ rdax ${input.in}, 0.25
115
+ mulx ${reg.gain} ; ACC = Input * DuckingGain
116
+
117
+ ; 4. Reverb Processing (Minimal 4 Allpass, 2 Delay Network)
118
+ rda ${mem.ap1}#, ${kap}
119
+ wrap ${mem.ap1}, -1.0
120
+ rda ${mem.ap2}#, ${kap}
121
+ wrap ${mem.ap2}, -1.0
122
+ rda ${mem.ap3}#, ${kap}
123
+ wrap ${mem.ap3}, -1.0
124
+ rda ${mem.ap4}#, ${kap}
125
+ wrap ${mem.ap4}, -1.0
126
+
127
+ ; Saving Allpass Output to write into the reverb tank
128
+ wrax ${reg.apout}, 0.0
129
+
130
+ ; Delay Loop 1 (Tank Left)
131
+ rdax ${reg.apout}, 1.0
132
+ rda ${mem.del2}#, 1.0
133
+ mulx ${reg.decay_val}
134
+ wra ${mem.del1}, 0.0
135
+
136
+ ; Delay Loop 2 (Tank Right)
137
+ rdax ${reg.apout}, 1.0
138
+ rda ${mem.del1}#, 1.0
139
+ mulx ${reg.decay_val}
140
+ wra ${mem.del2}, 0.0
141
+
142
+ ; 5. Output
143
+ rda ${mem.del1}#, 1.0
144
+ rda ${mem.del2}#, 1.0
145
+ wrax ${output.out}, 0.0