@audiofab-io/fv1-core 0.6.1 → 0.6.3
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 -156
- package/blocks/control/constant.atl +36 -36
- package/blocks/control/entropy_lfo.atl +74 -74
- package/blocks/control/envelope.atl +120 -120
- package/blocks/control/invert.atl +33 -33
- package/blocks/control/pot.atl +149 -149
- package/blocks/control/power.atl +76 -76
- package/blocks/control/ramp_lfo.atl +122 -122
- package/blocks/control/scale_offset.atl +84 -84
- package/blocks/control/sincos_lfo.atl +126 -126
- package/blocks/control/smoother.atl +48 -48
- package/blocks/control/tremolizer.atl +54 -54
- package/blocks/effects/delay/micro_stutter.atl +77 -77
- package/blocks/effects/delay/mn3011.atl +280 -280
- package/blocks/effects/delay/simple_delay.atl +96 -96
- package/blocks/effects/delay/triple_tap_delay.atl +176 -176
- package/blocks/effects/lo-fi/bit_mangler.atl +74 -74
- package/blocks/effects/lo-fi/chiptune.atl +311 -311
- package/blocks/effects/lo-fi/tape_degrade.atl +181 -181
- package/blocks/effects/modulation/chorus.atl +141 -141
- package/blocks/effects/modulation/chorus_4voice.atl +188 -188
- package/blocks/effects/modulation/flanger.atl +184 -184
- package/blocks/effects/modulation/harmonic_trem.atl +129 -129
- package/blocks/effects/modulation/phaser.atl +299 -299
- package/blocks/effects/pitch/octave_up_down.atl +80 -80
- package/blocks/effects/pitch/pitch_offset.atl +149 -149
- package/blocks/effects/pitch/pitch_offset_dual.atl +197 -197
- package/blocks/effects/pitch/pitch_shift.atl +115 -115
- package/blocks/effects/pitch/sub_octave.atl +100 -100
- package/blocks/effects/reverb/ducking_reverb.atl +145 -145
- package/blocks/effects/reverb/min_reverb.atl +132 -132
- package/blocks/effects/reverb/plate_reverb.atl +344 -344
- package/blocks/effects/reverb/room_reverb.atl +293 -293
- package/blocks/effects/reverb/smear.atl +90 -90
- package/blocks/effects/reverb/spring_reverb.atl +353 -353
- package/blocks/filter/1p_high_pass.atl +62 -62
- package/blocks/filter/1p_low_pass.atl +58 -58
- package/blocks/filter/auto_wah.atl +207 -207
- package/blocks/filter/bbd_loss.atl +79 -79
- package/blocks/filter/shelving_high_pass.atl +76 -76
- package/blocks/filter/shelving_low_pass.atl +76 -76
- package/blocks/filter/svf_2p.atl +116 -116
- package/blocks/gain_mix/crossfade.atl +93 -93
- package/blocks/gain_mix/crossfade2.atl +86 -86
- package/blocks/gain_mix/crossfade3.atl +71 -71
- package/blocks/gain_mix/gainboost.atl +54 -54
- package/blocks/gain_mix/mixer2.atl +76 -76
- package/blocks/gain_mix/mixer3.atl +109 -109
- package/blocks/gain_mix/mixer4.atl +151 -151
- package/blocks/gain_mix/volume.atl +50 -50
- package/blocks/io/adc.atl +53 -53
- package/blocks/io/dac.atl +61 -61
- package/blocks/other/stickynote.atl +24 -24
- package/blocks/other/tone_gen_adjustable.atl +137 -137
- package/blocks/other/tone_gen_fixed.atl +109 -109
- package/dist/blockDiagram/builtinBlocks.js +107 -107
- package/dist/blockDiagram/builtinBlocks.js.map +1 -1
- package/dist/simulator/FV1Simulator.d.ts +12 -0
- package/dist/simulator/FV1Simulator.d.ts.map +1 -1
- package/dist/simulator/FV1Simulator.js +47 -1
- package/dist/simulator/FV1Simulator.js.map +1 -1
- package/package.json +1 -1
|
@@ -33,8 +33,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
33
33
|
"description": "Constant value (0.0 to 1.0)."
|
|
34
34
|
}
|
|
35
35
|
],
|
|
36
|
-
"template": "; Constant value generator\
|
|
37
|
-
"_rawAtl": "---\
|
|
36
|
+
"template": "; Constant value generator\n@section main\n\nsof 0.0, ${param.constant}\nwrax ${output.value}, 0.0",
|
|
37
|
+
"_rawAtl": "---\n{\n \"type\": \"control.constant\",\n \"name\": \"Constant\",\n \"category\": \"Control\",\n \"description\": \"Generates a constant control value.\",\n \"color\": \"#FF9800\",\n \"width\": 140,\n \"labelTemplate\": \"${param.constant}\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"id\": \"value\",\n \"name\": \"Value\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"constant\",\n \"name\": \"Value\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Constant value (0.0 to 1.0).\"\n }\n ]\n}\n---\n; Constant value generator\n@section main\n\nsof 0.0, ${param.constant}\nwrax ${output.value}, 0.0\n"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"type": "control.entropy_lfo",
|
|
@@ -92,8 +92,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
92
92
|
"chaos_val",
|
|
93
93
|
"speed_val"
|
|
94
94
|
],
|
|
95
|
-
"template": "@section init\
|
|
96
|
-
"_rawAtl": "---\
|
|
95
|
+
"template": "@section init\nskp run, skip_init_entropy\nsof 0.0, 0.432 ; irrational seed\nwrax ${reg.x}, 0.0\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0\nskip_init_entropy:\n\n@section main\n; 1. Load CV inputs into registers\n@cv speed\nwrax ${reg.speed_val}, 0.0\n@cv chaos\nwrax ${reg.chaos_val}, 0.0\n\n; 2. Update Counter\nrdax ${reg.counter}, 1.0\nrdax ${reg.speed_val}, 0.002 ; Max speed ~70Hz (0.95 / 0.00203 / 32768)\nsof 1.0, 0.00003 ; Min speed ~1Hz (0.95 / 0.00003 / 32768)\nwrax ${reg.counter}, 1.0\n\n; 3. Check for Update Event\nsof 1.0, -0.95\nskp neg, ${local.SKIP_UPDATE}\n\n; --- Chaotic Map Block (Runs only on Trigger) ---\nclr ; MUST clear ACC after the counter check!\nrdax ${reg.x}, 1.0\nwrax ${reg.temp}, 1.0 ; temp = x\nsof -1.0, 0.999 ; ACC = 1 - x\nmulx ${reg.temp} ; ACC = x * (1 - x)\nsof 1.999, 0.0 ; Scale (x4)\nsof 1.999, 0.0 \nmulx ${reg.chaos_val} ; Apply chaos factor r\nwrax ${reg.x}, 1.0 ; update x\n\n; Kickstart: if |x| < 0.01, reset to seed (guards against map stalling at 0)\nabsa\nsof 1.0, -0.01\nskp gez, ${local.SKIP_KICK}\nsof 0.0, 0.432 ; irrational seed\nwrax ${reg.x}, 0.0\n${local.SKIP_KICK}:\n\n; Reset counter\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0\n\n${local.SKIP_UPDATE}:\n; 5. Output (CLEAN)\nclr ; Clear ACC before loading output to avoid counter pollution\nrdax ${reg.x}, 1.0\nwrax ${output.out}, 0.0",
|
|
96
|
+
"_rawAtl": "---\n{\n \"type\": \"control.entropy_lfo\",\n \"name\": \"Entropy LFO\",\n \"category\": \"Control\",\n \"description\": \"Chaotic Logistic Map (fixed: subsonic sweep and uppercase label hardening).\",\n \"color\": \"#f2b824\",\n \"inputs\": [\n { \"id\": \"speed\", \"name\": \"Speed\", \"type\": \"control\", \"required\": false, \"parameter\": \"speed\" },\n { \"id\": \"chaos\", \"name\": \"Chaos\", \"type\": \"control\", \"required\": false, \"parameter\": \"r_chaos\" }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Out\", \"type\": \"control\" }\n ],\n \"parameters\": [\n { \"id\": \"speed\", \"name\": \"Update Rate\", \"type\": \"number\", \"default\": 0.5, \"min\": 0, \"max\": 1, \"step\": 0.01 },\n { \"id\": \"r_chaos\", \"name\": \"Chaos (r)\", \"type\": \"number\", \"default\": 0.98, \"min\": 0.88, \"max\": 1.0, \"step\": 0.01 }\n ],\n \"registers\": [ \"x\", \"counter\", \"temp\", \"chaos_val\", \"speed_val\" ]\n}\n---\n@section init\nskp run, skip_init_entropy\nsof 0.0, 0.432 ; irrational seed\nwrax ${reg.x}, 0.0\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0\nskip_init_entropy:\n\n@section main\n; 1. Load CV inputs into registers\n@cv speed\nwrax ${reg.speed_val}, 0.0\n@cv chaos\nwrax ${reg.chaos_val}, 0.0\n\n; 2. Update Counter\nrdax ${reg.counter}, 1.0\nrdax ${reg.speed_val}, 0.002 ; Max speed ~70Hz (0.95 / 0.00203 / 32768)\nsof 1.0, 0.00003 ; Min speed ~1Hz (0.95 / 0.00003 / 32768)\nwrax ${reg.counter}, 1.0\n\n; 3. Check for Update Event\nsof 1.0, -0.95\nskp neg, ${local.SKIP_UPDATE}\n\n; --- Chaotic Map Block (Runs only on Trigger) ---\nclr ; MUST clear ACC after the counter check!\nrdax ${reg.x}, 1.0\nwrax ${reg.temp}, 1.0 ; temp = x\nsof -1.0, 0.999 ; ACC = 1 - x\nmulx ${reg.temp} ; ACC = x * (1 - x)\nsof 1.999, 0.0 ; Scale (x4)\nsof 1.999, 0.0 \nmulx ${reg.chaos_val} ; Apply chaos factor r\nwrax ${reg.x}, 1.0 ; update x\n\n; Kickstart: if |x| < 0.01, reset to seed (guards against map stalling at 0)\nabsa\nsof 1.0, -0.01\nskp gez, ${local.SKIP_KICK}\nsof 0.0, 0.432 ; irrational seed\nwrax ${reg.x}, 0.0\n${local.SKIP_KICK}:\n\n; Reset counter\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0\n\n${local.SKIP_UPDATE}:\n; 5. Output (CLEAN)\nclr ; Clear ACC before loading output to avoid counter pollution\nrdax ${reg.x}, 1.0\nwrax ${output.out}, 0.0\n"
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"type": "control.envelope",
|
|
@@ -168,8 +168,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
168
168
|
"LAVG",
|
|
169
169
|
"TEMP"
|
|
170
170
|
],
|
|
171
|
-
"template": "; Envelope Follower\
|
|
172
|
-
"_rawAtl": "---\
|
|
171
|
+
"template": "; Envelope Follower\n; Based on EnvelopeControlCADBlock.java\n\n@section main\n@if pinConnected(audio)\n\n; --- Pre-Detection Boost ---\n; RDAX coefficient (up to 1.99x) + fixed SOF 2x stage = up to ~4x total headroom boost.\nrdax ${input.audio}, ${param.gain} ; Boost via RDAX coefficient (0.5–1.99x)\nsof 1.99, 0.0 ; Additional 2x → env covers the full 0–1 range for normal playing levels\nabsa ; Full-wave rectify\n@if pinConnected(sens)\nmulx ${input.sens} ; Pot scales overall sensitivity (0 = off, 1.0 = full)\n@endif\n\n; --- Single Slope (Average Follower) ---\n; Computes a running average of the magnitude using a first-order low-pass filter.\nrdfx ${reg.AVG}, ${param.attack}\nwrax ${reg.AVG}, 0.0 ; Clear ACC to process Dual Slope next\n\n; --- Dual Slope (Peak Follower) ---\n; Follows the peak of the average signal with an exponential decay.\n; 1. Compute decayed peak: TEMP = LAVG * (1 - decay)\nrdax ${reg.LAVG}, 1.0\nsof -${param.decay}, 0.0 ; Apply coefficient as multiplier (-decay)\nrdax ${reg.LAVG}, 1.0 ; ACC = LAVG - decay*LAVG\nwrax ${reg.TEMP}, 0.0 ; Store decayed peak, clear ACC\n\n; 2. Update LAVG: LAVG = max(AVG, decayed_peak)\nrdax ${reg.AVG}, 1.0\nmaxx ${reg.TEMP}, 1.0\nwrax ${reg.LAVG}, 0.0 ; Update LAVG with the maximum of current and decayed\n\n; --- Output Routing ---\n@if pinConnected(single)\nrdax ${reg.AVG}, 1.0\nwrax ${output.single}, 0.0\n@endif\n\n@if pinConnected(dual)\nrdax ${reg.LAVG}, 1.0\nwrax ${output.dual}, 0.0\n@endif\n\n@endif",
|
|
172
|
+
"_rawAtl": "---\n{\n \"type\": \"control.envelope\",\n \"category\": \"Control\",\n \"name\": \"Envelope Follower\",\n \"description\": \"Multi-mode envelope follower based on the SpinCAD 'Envelope' block algorithm. Outputs both a Single Slope (average) and a Dual Slope (peak with decay) follower.\",\n \"labelTemplate\": \"\",\n \"color\": \"#f2b824\",\n \"inputs\": [\n {\n \"id\": \"audio\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"sens\",\n \"name\": \"Sensitivity\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"gain\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"single\",\n \"name\": \"Single Slope\",\n \"type\": \"control\"\n },\n {\n \"id\": \"dual\",\n \"name\": \"Dual Slope\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"gain\",\n \"name\": \"Sensitivity\",\n \"type\": \"number\",\n \"default\": 1.5,\n \"min\": 0.5,\n \"max\": 1.99,\n \"step\": 0.01,\n \"description\": \"Pre-detection boost (up to ~4x with internal SOF stage). Higher values make the envelope respond to quieter signals.\"\n },\n {\n \"id\": \"attack\",\n \"name\": \"Attack Rate\",\n \"type\": \"number\",\n \"default\": 0.78,\n \"min\": 0.1,\n \"max\": 20.0,\n \"step\": 0.01,\n \"conversion\": \"LOGFREQ\",\n \"description\": \"Corner frequency for the Single Slope (average) follower. 0.78 Hz ≈ 0.00015 coefficient.\"\n },\n {\n \"id\": \"decay\",\n \"name\": \"Decay Rate\",\n \"type\": \"number\",\n \"default\": 0.52,\n \"min\": 0.1,\n \"max\": 10.0,\n \"step\": 0.01,\n \"conversion\": \"LOGFREQ\",\n \"description\": \"Release frequency for the Dual Slope (peak) follower. 0.52 Hz ≈ 0.0001 coefficient.\"\n }\n ],\n \"registers\": [\n \"AVG\",\n \"LAVG\",\n \"TEMP\"\n ]\n}\n---\n; Envelope Follower\n; Based on EnvelopeControlCADBlock.java\n\n@section main\n@if pinConnected(audio)\n\n; --- Pre-Detection Boost ---\n; RDAX coefficient (up to 1.99x) + fixed SOF 2x stage = up to ~4x total headroom boost.\nrdax ${input.audio}, ${param.gain} ; Boost via RDAX coefficient (0.5–1.99x)\nsof 1.99, 0.0 ; Additional 2x → env covers the full 0–1 range for normal playing levels\nabsa ; Full-wave rectify\n@if pinConnected(sens)\nmulx ${input.sens} ; Pot scales overall sensitivity (0 = off, 1.0 = full)\n@endif\n\n; --- Single Slope (Average Follower) ---\n; Computes a running average of the magnitude using a first-order low-pass filter.\nrdfx ${reg.AVG}, ${param.attack}\nwrax ${reg.AVG}, 0.0 ; Clear ACC to process Dual Slope next\n\n; --- Dual Slope (Peak Follower) ---\n; Follows the peak of the average signal with an exponential decay.\n; 1. Compute decayed peak: TEMP = LAVG * (1 - decay)\nrdax ${reg.LAVG}, 1.0\nsof -${param.decay}, 0.0 ; Apply coefficient as multiplier (-decay)\nrdax ${reg.LAVG}, 1.0 ; ACC = LAVG - decay*LAVG\nwrax ${reg.TEMP}, 0.0 ; Store decayed peak, clear ACC\n\n; 2. Update LAVG: LAVG = max(AVG, decayed_peak)\nrdax ${reg.AVG}, 1.0\nmaxx ${reg.TEMP}, 1.0\nwrax ${reg.LAVG}, 0.0 ; Update LAVG with the maximum of current and decayed\n\n; --- Output Routing ---\n@if pinConnected(single)\nrdax ${reg.AVG}, 1.0\nwrax ${output.single}, 0.0\n@endif\n\n@if pinConnected(dual)\nrdax ${reg.LAVG}, 1.0\nwrax ${output.dual}, 0.0\n@endif\n\n@endif"
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
"type": "control.invert",
|
|
@@ -193,8 +193,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
193
193
|
}
|
|
194
194
|
],
|
|
195
195
|
"parameters": [],
|
|
196
|
-
"template": "; Control Invert\
|
|
197
|
-
"_rawAtl": "---\
|
|
196
|
+
"template": "; Control Invert\n@section main\n\n@if pinConnected(input)\nrdax ${input.input}, 1.0\nsof -0.999, 0.999\nwrax ${output.output}, 0.0\n@endif",
|
|
197
|
+
"_rawAtl": "---\n{\n \"type\": \"control.invert\",\n \"name\": \"Invert\",\n \"category\": \"Control\",\n \"description\": \"Inverts a control signal: 0.0→1.0, 1.0→0.0.\",\n \"color\": \"#f2b824\",\n \"width\": 140,\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Input\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": []\n}\n---\n; Control Invert\n@section main\n\n@if pinConnected(input)\nrdax ${input.input}, 1.0\nsof -0.999, 0.999\nwrax ${output.output}, 0.0\n@endif\n"
|
|
198
198
|
},
|
|
199
199
|
{
|
|
200
200
|
"type": "control.power",
|
|
@@ -241,8 +241,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
241
241
|
"registers": [
|
|
242
242
|
"value"
|
|
243
243
|
],
|
|
244
|
-
"template": "@section header\
|
|
245
|
-
"_rawAtl": "---\
|
|
244
|
+
"template": "@section header\n@comment \"Generated from spincad source file PowerControlCADBlock.java\"\n\n@section main\n; Applies a non-linear curve (square) optionally inverted/flipped\nrdax\t${input.in},\t1.0\n@if ${invert} == true\n; ---Invert\nsof\t-0.9990234375,\t0.9990234375\n@endif\nwrax\t${reg.value},\t1.0\n\n@if ${power} >= 2\nmulx\t${reg.value}\n@endif\n@if ${power} >= 3\nmulx\t${reg.value}\n@endif\n@if ${power} >= 4\nmulx\t${reg.value}\n@endif\n@if ${power} >= 5\nmulx\t${reg.value}\n@endif\n@if ${flip} == true\n; ---Flip\nsof\t-0.9990234375,\t0.9990234375\n@endif\nwrax\t${output.out},\t0",
|
|
245
|
+
"_rawAtl": "---\n{\n \"type\": \"control.power\",\n \"category\": \"Control\",\n \"name\": \"Power\",\n \"description\": \"Applies a non-linear curve optionally inverted/flipped\",\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"power\",\n \"name\": \"Power\",\n \"type\": \"number\",\n \"default\": 3,\n \"min\": 1,\n \"max\": 5,\n \"step\": 1\n },\n {\n \"id\": \"invert\",\n \"name\": \"Invert\",\n \"type\": \"boolean\",\n \"default\": false\n },\n {\n \"id\": \"flip\",\n \"name\": \"Flip\",\n \"type\": \"boolean\",\n \"default\": false\n }\n ],\n \"registers\": [\n \"value\"\n ]\n}\n---\n@section header\n@comment \"Generated from spincad source file PowerControlCADBlock.java\"\n\n@section main\n; Applies a non-linear curve (square) optionally inverted/flipped\nrdax\t${input.in},\t1.0\n@if ${invert} == true\n; ---Invert\nsof\t-0.9990234375,\t0.9990234375\n@endif\nwrax\t${reg.value},\t1.0\n\n@if ${power} >= 2\nmulx\t${reg.value}\n@endif\n@if ${power} >= 3\nmulx\t${reg.value}\n@endif\n@if ${power} >= 4\nmulx\t${reg.value}\n@endif\n@if ${power} >= 5\nmulx\t${reg.value}\n@endif\n@if ${flip} == true\n; ---Flip\nsof\t-0.9990234375,\t0.9990234375\n@endif\nwrax\t${output.out},\t0"
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
248
|
"type": "control.ramp_lfo",
|
|
@@ -329,8 +329,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
329
329
|
"description": "Internal amplitude limit of the WLDR instruction."
|
|
330
330
|
}
|
|
331
331
|
],
|
|
332
|
-
"template": "@if ${param.lfoSel} == 0\
|
|
333
|
-
"_rawAtl": "---\
|
|
332
|
+
"template": "@if ${param.lfoSel} == 0\n@equals lfoNum RMP0\n@equals lfoRateReg RMP0_RATE\n@else\n@equals lfoNum RMP1\n@equals lfoRateReg RMP1_RATE\n@endif\n\n; Ramp LFO generator\n@section init\n; WLDR accepts discrete amplitudes: 512, 1024, 2048, 4096.\n; Negative frequencies slope Upwards natively. Positive frequencies slope Downwards.\nwldr ${lfoNum}, ${param.speed} * 512, ${param.amplitude}\n\n@section main\n\n; Speed modulation (-1.0 to 1.0 covers -32768 to 32767 natively)\n@if pinConnected(speed)\n rdax ${input.speed}, 1.0\n wrax ${lfoRateReg}, 0.0\n@endif\n\n; Ramp output\n@if pinConnected(ramp)\n cho rdal, ${lfoNum}\n\n ; Apply width CV scale if connected\n @if pinConnected(width)\n mulx ${input.width}\n @endif\n\n wrax ${output.ramp}, 0.0\n@endif\n\n; Triangle output\n@if pinConnected(triangle)\n cho rdal, ${lfoNum}\n \n ; SpinCAD derivation: scale by 1.999 to stretch 0..1 to 0..2\n ; Shift down by exactly half the internal WLDR amplitude ratio\n ; Then apply ABSA to fold it back into a Triangle!\n @equals amp_ratio ${param.amplitude} / 4096.0\n sof 1.999, -0.5 * ${amp_ratio}\n absa\n\n ; Apply width CV scale if connected\n @if pinConnected(width)\n mulx ${input.width}\n @endif\n\n wrax ${output.triangle}, 0.0\n@endif",
|
|
333
|
+
"_rawAtl": "---\n{\n \"type\": \"control.ramp_lfo\",\n \"name\": \"Ramp LFO\",\n \"category\": \"Control\",\n \"description\": \"Ramp LFO generator with adjustable rate, amplitude, slope, and dual outputs (Ramp / Triangle).\",\n \"color\": \"#f2b824\",\n \"labelTemplate\": \"${param.lfoSel == 0 ? 'RMP0' : 'RMP1'}\",\n \"inputs\": [\n {\n \"id\": \"speed\",\n \"name\": \"Speed\",\n \"type\": \"control\"\n },\n {\n \"id\": \"width\",\n \"name\": \"Level (Width)\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"ramp\",\n \"name\": \"Ramp Out\",\n \"type\": \"control\"\n },\n {\n \"id\": \"triangle\",\n \"name\": \"Triangle Out\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Selection\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"value\": 0, \"label\": \"RMP0\" },\n { \"value\": 1, \"label\": \"RMP1\" }\n ],\n \"description\": \"Which LFO oscillator to use (0 or 1).\"\n },\n {\n \"id\": \"speed\",\n \"name\": \"Speed\",\n \"type\": \"number\",\n \"default\": 6.25,\n \"min\": -32,\n \"max\": 64,\n \"step\": 0.01,\n \"description\": \"Base LFO rate (used if Speed control is not connected).\"\n },\n {\n \"id\": \"amplitude\",\n \"name\": \"Base Amplitude\",\n \"type\": \"select\",\n \"default\": 4096,\n \"options\": [\n { \"value\": 4096, \"label\": \"Full (4096)\" },\n { \"value\": 2048, \"label\": \"Half (2048)\" },\n { \"value\": 1024, \"label\": \"Quarter (1024)\" },\n { \"value\": 512, \"label\": \"Eighth (512)\" }\n ],\n \"description\": \"Internal amplitude limit of the WLDR instruction.\"\n }\n ]\n}\n---\n@if ${param.lfoSel} == 0\n@equals lfoNum RMP0\n@equals lfoRateReg RMP0_RATE\n@else\n@equals lfoNum RMP1\n@equals lfoRateReg RMP1_RATE\n@endif\n\n; Ramp LFO generator\n@section init\n; WLDR accepts discrete amplitudes: 512, 1024, 2048, 4096.\n; Negative frequencies slope Upwards natively. Positive frequencies slope Downwards.\nwldr ${lfoNum}, ${param.speed} * 512, ${param.amplitude}\n\n@section main\n\n; Speed modulation (-1.0 to 1.0 covers -32768 to 32767 natively)\n@if pinConnected(speed)\n rdax ${input.speed}, 1.0\n wrax ${lfoRateReg}, 0.0\n@endif\n\n; Ramp output\n@if pinConnected(ramp)\n cho rdal, ${lfoNum}\n\n ; Apply width CV scale if connected\n @if pinConnected(width)\n mulx ${input.width}\n @endif\n\n wrax ${output.ramp}, 0.0\n@endif\n\n; Triangle output\n@if pinConnected(triangle)\n cho rdal, ${lfoNum}\n \n ; SpinCAD derivation: scale by 1.999 to stretch 0..1 to 0..2\n ; Shift down by exactly half the internal WLDR amplitude ratio\n ; Then apply ABSA to fold it back into a Triangle!\n @equals amp_ratio ${param.amplitude} / 4096.0\n sof 1.999, -0.5 * ${amp_ratio}\n absa\n\n ; Apply width CV scale if connected\n @if pinConnected(width)\n mulx ${input.width}\n @endif\n\n wrax ${output.triangle}, 0.0\n@endif\n"
|
|
334
334
|
},
|
|
335
335
|
{
|
|
336
336
|
"type": "control.scale_offset",
|
|
@@ -396,8 +396,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
396
396
|
"description": "Maximum value of output range (-2.0 to 1.0)."
|
|
397
397
|
}
|
|
398
398
|
],
|
|
399
|
-
"template": "; Scale/Offset\
|
|
400
|
-
"_rawAtl": "---\
|
|
399
|
+
"template": "; Scale/Offset\n@section main\n\n@if pinConnected(ctrl_in)\n@minusDouble outRange outHigh outLow\n@minusDouble inRange inHigh inLow\n@divideDouble scale outRange inRange\n@multiplyDouble inLowScale inLow scale\n@minusDouble offset outLow inLowScale\n\n@assert inRange > 0, \"Scale/Offset: Input range is invalid.\"\n@assert outRange > 0, \"Scale/Offset: Output range is invalid.\"\n\nrdax ${input.ctrl_in}, 1.0\nsof ${scale}, ${offset}\nwrax ${output.ctrl_out}, 0.0\n@endif",
|
|
400
|
+
"_rawAtl": "---\n{\n \"type\": \"control.scale_offset\",\n \"name\": \"Scale/Offset\",\n \"category\": \"Control\",\n \"description\": \"Scale and offset a control signal to remap input range to output range.\",\n \"color\": \"#f2b824\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"ctrl_in\",\n \"name\": \"Control\",\n \"type\": \"control\",\n \"required\": true\n }\n ],\n \"outputs\": [\n {\n \"id\": \"ctrl_out\",\n \"name\": \"Control\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"inLow\",\n \"name\": \"Input Low\",\n \"type\": \"number\",\n \"default\": 0,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Minimum value of input range (0.0-1.0).\"\n },\n {\n \"id\": \"inHigh\",\n \"name\": \"Input High\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Maximum value of input range (0.0-1.0).\"\n },\n {\n \"id\": \"outLow\",\n \"name\": \"Output Low\",\n \"type\": \"number\",\n \"default\": 0,\n \"min\": -2,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Minimum value of output range (-2.0 to 1.0).\"\n },\n {\n \"id\": \"outHigh\",\n \"name\": \"Output High\",\n \"type\": \"number\",\n \"default\": 0.75,\n \"min\": -2,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Maximum value of output range (-2.0 to 1.0).\"\n }\n ]\n}\n---\n; Scale/Offset\n@section main\n\n@if pinConnected(ctrl_in)\n@minusDouble outRange outHigh outLow\n@minusDouble inRange inHigh inLow\n@divideDouble scale outRange inRange\n@multiplyDouble inLowScale inLow scale\n@minusDouble offset outLow inLowScale\n\n@assert inRange > 0, \"Scale/Offset: Input range is invalid.\"\n@assert outRange > 0, \"Scale/Offset: Output range is invalid.\"\n\nrdax ${input.ctrl_in}, 1.0\nsof ${scale}, ${offset}\nwrax ${output.ctrl_out}, 0.0\n@endif\n"
|
|
401
401
|
},
|
|
402
402
|
{
|
|
403
403
|
"type": "control.sincos_lfo",
|
|
@@ -487,8 +487,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
487
487
|
"description": "Output signal range."
|
|
488
488
|
}
|
|
489
489
|
],
|
|
490
|
-
"template": "@if ${param.lfoSel} == 0\
|
|
491
|
-
"_rawAtl": "---\
|
|
490
|
+
"template": "@if ${param.lfoSel} == 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRangeReg SIN0_RANGE\n@equals lfoCos COS0\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRangeReg SIN1_RANGE\n@equals lfoCos COS1\n@endif\n\n; Sin/Cos LFO generator\n@section init\nwlds ${lfoNum}, ${param.speed}, ${param.width} * 32767\n\n@section main\n\n; Speed modulation (0 to 20 Hz -> 0 to 160 int)\n@if pinConnected(speed)\nrdax ${input.speed}, 160.0 / 512.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n; Width modulation (0 to 1.0 fullswing)\n@if pinConnected(width)\nrdax ${input.width}, 1.0\nwrax ${lfoRangeReg}, 0.0\n@endif\n\n; Sine output\n@if pinConnected(sine)\ncho rdal, ${lfoNum}\n@if param.outputRange == 'unipolar'\nsof 0.5, 0.5\n@endif\nwrax ${output.sine}, 0.0\n@endif\n\n; Cosine output\n@if pinConnected(cosine)\ncho rdal, ${lfoCos}\n@if param.outputRange == 'unipolar'\nsof 0.5, 0.5\n@endif\nwrax ${output.cosine}, 0.0\n@endif",
|
|
491
|
+
"_rawAtl": "---\n{\n \"type\": \"control.sincos_lfo\",\n \"name\": \"Sin/Cos LFO\",\n \"category\": \"Control\",\n \"description\": \"Sine and cosine LFO generator with adjustable rate and width.\",\n \"color\": \"#f2b824\",\n \"labelTemplate\": \"${param.lfoSel == 0 ? 'LFO0' : 'LFO1'}\",\n \"inputs\": [\n {\n \"id\": \"speed\",\n \"name\": \"Speed\",\n \"type\": \"control\"\n },\n {\n \"id\": \"width\",\n \"name\": \"Width\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"sine\",\n \"name\": \"Sine\",\n \"type\": \"control\"\n },\n {\n \"id\": \"cosine\",\n \"name\": \"Cosine\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Selection\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"value\": 0, \"label\": \"LFO0\" },\n { \"value\": 1, \"label\": \"LFO1\" }\n ],\n \"description\": \"Which LFO oscillator to use (0 or 1).\"\n },\n {\n \"id\": \"speed\",\n \"name\": \"Speed (Hz)\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 20,\n \"step\": 0.01,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Base LFO rate\"\n },\n {\n \"id\": \"width\",\n \"name\": \"Width (1.0 equals full swing)\",\n \"type\": \"number\",\n \"default\": 0.25,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Base LFO width\"\n },\n {\n \"id\": \"outputRange\",\n \"name\": \"Output Range\",\n \"type\": \"select\",\n \"default\": \"bipolar\",\n \"options\": [\n { \"value\": \"bipolar\", \"label\": \"-1.0 to 1.0\" },\n { \"value\": \"unipolar\", \"label\": \"0.0 to 1.0\" }\n ],\n \"description\": \"Output signal range.\"\n }\n ]\n}\n---\n@if ${param.lfoSel} == 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRangeReg SIN0_RANGE\n@equals lfoCos COS0\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRangeReg SIN1_RANGE\n@equals lfoCos COS1\n@endif\n\n; Sin/Cos LFO generator\n@section init\nwlds ${lfoNum}, ${param.speed}, ${param.width} * 32767\n\n@section main\n\n; Speed modulation (0 to 20 Hz -> 0 to 160 int)\n@if pinConnected(speed)\nrdax ${input.speed}, 160.0 / 512.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n; Width modulation (0 to 1.0 fullswing)\n@if pinConnected(width)\nrdax ${input.width}, 1.0\nwrax ${lfoRangeReg}, 0.0\n@endif\n\n; Sine output\n@if pinConnected(sine)\ncho rdal, ${lfoNum}\n@if param.outputRange == 'unipolar'\nsof 0.5, 0.5\n@endif\nwrax ${output.sine}, 0.0\n@endif\n\n; Cosine output\n@if pinConnected(cosine)\ncho rdal, ${lfoCos}\n@if param.outputRange == 'unipolar'\nsof 0.5, 0.5\n@endif\nwrax ${output.cosine}, 0.0\n@endif\n"
|
|
492
492
|
},
|
|
493
493
|
{
|
|
494
494
|
"type": "control.smoother",
|
|
@@ -525,8 +525,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
525
525
|
],
|
|
526
526
|
"color": "#f2f224",
|
|
527
527
|
"registers": [],
|
|
528
|
-
"template": "@section header\
|
|
529
|
-
"_rawAtl": "---\
|
|
528
|
+
"template": "@section header\n@comment \"Generated from spincad source file control_smoother.spincad\"\nequ filt ${freq}\n\n@section main\n@if pinConnected(input)\nrdax ${input.input}, 1.0\nrdfx ${output.output}, filt\nwrax ${output.output}, 0.0\n@endif",
|
|
529
|
+
"_rawAtl": "---\n{\n \"type\": \"control.smoother\",\n \"category\": \"Control\",\n \"name\": \"Smoother\",\n \"description\": \"Applies a simple low pass filter to smooth the control signal\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"CV In\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"CV Out\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"freq\",\n \"name\": \"Frequency\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.5,\n \"max\": 15.0,\n \"step\": 0.01,\n \"conversion\": \"LOGFREQ\",\n \"labelTemplate\": \"${freq} Hz\",\n \"description\": \"Smoother cutoff frequency in Hz. Lower values = slower/smoother response.\"\n }\n ],\n \"color\": \"#f2f224\",\n \"registers\": []\n}\n---\n@section header\n@comment \"Generated from spincad source file control_smoother.spincad\"\nequ filt ${freq}\n\n@section main\n@if pinConnected(input)\nrdax ${input.input}, 1.0\nrdfx ${output.output}, filt\nwrax ${output.output}, 0.0\n@endif\n"
|
|
530
530
|
},
|
|
531
531
|
{
|
|
532
532
|
"type": "control.tremolizer",
|
|
@@ -564,8 +564,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
564
564
|
}
|
|
565
565
|
],
|
|
566
566
|
"color": "#f2f224",
|
|
567
|
-
"template": "@section header\
|
|
568
|
-
"_rawAtl": "---\
|
|
567
|
+
"template": "@section header\n@comment \"Generated from spincad source file tremolizer.spincad\"\n\n@section main\n// This control block takes a signal (usually an LFO) that goes from 0.0 to 1.0 and \n// allows you to adjust the ${input.width} via a control ${input.input}.\n// There is also a control panel setting for maximum ${depth}\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(input)\nrdax ${input.input}, ${depth}\n@if pinConnected(width)\nmulx ${input.width}\n@endif\nsof -0.999, 0.999\nwrax ${output.output}, 0.0\n@endif",
|
|
568
|
+
"_rawAtl": "---\n{\n \"type\": \"control.tremolizer\",\n \"category\": \"Control\",\n \"name\": \"Tremolizer\",\n \"description\": \"Adjusts the LFO width based on a control signal\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"LFO Input\",\n \"type\": \"control\"\n },\n {\n \"id\": \"width\",\n \"name\": \"LFO Width\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Control Output\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"depth\",\n \"name\": \"Depth\",\n \"type\": \"number\",\n \"min\": 0.0,\n \"max\": 1.0,\n \"default\": 0.5,\n \"step\": 0.01\n }\n ],\n \"color\": \"#f2f224\"\n}\n---\n@section header\n@comment \"Generated from spincad source file tremolizer.spincad\"\n\n@section main\n// This control block takes a signal (usually an LFO) that goes from 0.0 to 1.0 and \n// allows you to adjust the ${input.width} via a control ${input.input}.\n// There is also a control panel setting for maximum ${depth}\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(input)\nrdax ${input.input}, ${depth}\n@if pinConnected(width)\nmulx ${input.width}\n@endif\nsof -0.999, 0.999\nwrax ${output.output}, 0.0\n@endif"
|
|
569
569
|
},
|
|
570
570
|
{
|
|
571
571
|
"type": "effects.bit_mangler",
|
|
@@ -638,8 +638,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
638
638
|
"temp_mix",
|
|
639
639
|
"dry_val"
|
|
640
640
|
],
|
|
641
|
-
"template": "; The Bit-Mangler - Namespaced SRR\
|
|
642
|
-
"_rawAtl": "---\
|
|
641
|
+
"template": "; The Bit-Mangler - Namespaced SRR\n; Fixes jump collisions and hardware register leakage (Register 0).\n\n@section main\n@if pinConnected(input)\n; 0. Initialization (First Run only)\nskp run, ${local.SKIP_INIT}\nrdax ${input.input}, 1.0\nwrax ${reg.held}, 0.0\n${local.SKIP_INIT}:\n\n; 1. Envelope Follower\nclr\nrdax ${input.input}, 1.0\nabsa\nrdfx ${reg.env}, 0.001\nwrax ${reg.env}, 0.0\n\n; 2. S&H Counter\n; Increment = base_rate + (env * sens)\n@cv sensCV ; ACC = sensCV\nmulx ${reg.env} ; ACC = sensCV * env\nrdax ${reg.counter}, 1.0 ; ACC = (sensCV * env) + counter\nsof 1.0, ${param.base_rate} ; ACC = (sensCV * env) + counter + base_rate\nwrax ${reg.counter}, 1.0\n\n; 3. Check for Sample Event (trigger at 0.99)\nsof 1.0, -0.99\nskp neg, ${local.SKIP_SAMPLE}\n\n; --- Sample Block (Runs only on Trigger) ---\nclr ; MUST clear ACC to avoid using the 'counter-0.95' residual!\nrdax ${input.input}, 1.0\nwrax ${reg.held}, 0.0 ; Update S&H value\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0 ; Reset counter\n\n${local.SKIP_SAMPLE}:\n; 4. Final Output Mix: Out = Dry + (Wet - Dry) * Mix\nclr ; Clear ACC after skip to avoid counter pollution\n@cv mixCV ; Load mix value (0 to 1) \nwrax ${reg.temp_mix}, 0.0\n\nrdax ${input.input}, 1.0 ; Dry signal\nwrax ${reg.dry_val}, -1.0 ; dry_val = dry, ACC = -dry\nrdax ${reg.held}, 1.0 ; ACC = wet - dry\nmulx ${reg.temp_mix} ; ACC = (wet - dry) * mix\nrdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix\nwrax ${output.out}, 0.0\n@endif",
|
|
642
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.bit_mangler\",\n \"name\": \"The Bit-Mangler\",\n \"category\": \"Effects\",\n \"subcategory\": \"Lo-Fi\",\n \"description\": \"An enveloped sample-rate reducer (Fixed: Namespaced labels and gain staging).\",\n \"color\": \"#6f24f2\",\n \"inputs\": [\n { \"id\": \"input\", \"name\": \"Audio In\", \"type\": \"audio\" },\n { \"id\": \"sensCV\", \"name\": \"Sensitivity\", \"type\": \"control\", \"required\": false, \"parameter\": \"sens\" },\n { \"id\": \"mixCV\", \"name\": \"Mix\", \"type\": \"control\", \"required\": false, \"parameter\": \"mix\" }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Audio Out\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n { \"id\": \"base_rate\", \"name\": \"Crush Step\", \"type\": \"number\", \"default\": 0.05, \"min\": 0, \"max\": 0.5, \"step\": 0.001 },\n { \"id\": \"sens\", \"name\": \"Env Sensitivity\", \"type\": \"number\", \"default\": 0.1, \"min\": 0, \"max\": 1, \"step\": 0.01 },\n { \"id\": \"mix\", \"name\": \"Dry/Wet Mix\", \"type\": \"number\", \"default\": 1.0, \"min\": 0, \"max\": 1, \"step\": 0.01 }\n ],\n \"registers\": [ \"env\", \"counter\", \"held\", \"temp_mix\", \"dry_val\" ]\n}\n---\n; The Bit-Mangler - Namespaced SRR\n; Fixes jump collisions and hardware register leakage (Register 0).\n\n@section main\n@if pinConnected(input)\n; 0. Initialization (First Run only)\nskp run, ${local.SKIP_INIT}\nrdax ${input.input}, 1.0\nwrax ${reg.held}, 0.0\n${local.SKIP_INIT}:\n\n; 1. Envelope Follower\nclr\nrdax ${input.input}, 1.0\nabsa\nrdfx ${reg.env}, 0.001\nwrax ${reg.env}, 0.0\n\n; 2. S&H Counter\n; Increment = base_rate + (env * sens)\n@cv sensCV ; ACC = sensCV\nmulx ${reg.env} ; ACC = sensCV * env\nrdax ${reg.counter}, 1.0 ; ACC = (sensCV * env) + counter\nsof 1.0, ${param.base_rate} ; ACC = (sensCV * env) + counter + base_rate\nwrax ${reg.counter}, 1.0\n\n; 3. Check for Sample Event (trigger at 0.99)\nsof 1.0, -0.99\nskp neg, ${local.SKIP_SAMPLE}\n\n; --- Sample Block (Runs only on Trigger) ---\nclr ; MUST clear ACC to avoid using the 'counter-0.95' residual!\nrdax ${input.input}, 1.0\nwrax ${reg.held}, 0.0 ; Update S&H value\nsof 0.0, 0.0\nwrax ${reg.counter}, 0.0 ; Reset counter\n\n${local.SKIP_SAMPLE}:\n; 4. Final Output Mix: Out = Dry + (Wet - Dry) * Mix\nclr ; Clear ACC after skip to avoid counter pollution\n@cv mixCV ; Load mix value (0 to 1) \nwrax ${reg.temp_mix}, 0.0\n\nrdax ${input.input}, 1.0 ; Dry signal\nwrax ${reg.dry_val}, -1.0 ; dry_val = dry, ACC = -dry\nrdax ${reg.held}, 1.0 ; ACC = wet - dry\nmulx ${reg.temp_mix} ; ACC = (wet - dry) * mix\nrdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix\nwrax ${output.out}, 0.0\n@endif\n"
|
|
643
643
|
},
|
|
644
644
|
{
|
|
645
645
|
"type": "effects.delay.mn3011",
|
|
@@ -806,8 +806,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
806
806
|
"size": "max_delay"
|
|
807
807
|
}
|
|
808
808
|
],
|
|
809
|
-
"template": "@section header\
|
|
810
|
-
"_rawAtl": "---\
|
|
809
|
+
"template": "@section header\n ; MN3011 Target Ratios (stage / 3328)\n equ t1_ratio 0.118990 ; 396/3328\n equ t2_ratio 0.198918 ; 662/3328\n equ t3_ratio 0.358774 ; 1194/3328\n equ t4_ratio 0.518630 ; 1726/3328\n equ t5_ratio 0.838341 ; 2790/3328\n equ t6_ratio 1.0 ; 3328/3328\n \n@section main\n ; 1. Feedback Processing\n @if pinConnected(fb_in)\n rdax ${input.fb_in}, 1.0\n @mulcv fb_level_cv\n sof ${param.fbk_gain}, 0.0\n @else\n clr\n @endif\n \n ; 2. Input Summing & Write\n rdax ${input.in}, ${param.input_gain}\n wra ${mem.buffer}, 0.0\n\n ; 3. Multitap Summation\n @if pinConnected(time_cv)\n ; --- Dynamic Time (ADDR_PTR mode) ---\n @cv time_cv\n wrax ${reg.pot_val}, 0.0\n \n ; Tap 6 (processed first for fb_out convenience)\n rdax ${reg.pot_val}, 1.0\n sof t6_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa 1.0\n @if pinConnected(tap6)\n wrax ${output.tap6}, 1.0\n @endif\n sof ${param.tap6_gain}, 0.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 1\n rdax ${reg.pot_val}, 1.0\n sof t1_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap1_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 2\n rdax ${reg.pot_val}, 1.0\n sof t2_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap2_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 3\n rdax ${reg.pot_val}, 1.0\n sof t3_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap3_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 4\n rdax ${reg.pot_val}, 1.0\n sof t4_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap4_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 5\n rdax ${reg.pot_val}, 1.0\n sof t5_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap5_gain}\n rdax ${reg.mix_acc}, 1.0\n \n @else\n ; --- Static Time (Fixed RDA mode) ---\n \n ; Tap 6\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t6_ratio), 1.0\n @if pinConnected(tap6)\n wrax ${output.tap6}, 1.0\n @endif\n sof ${param.tap6_gain}, 0.0\n \n ; Tap 5\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t5_ratio), ${param.tap5_gain}\n \n ; Tap 4\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t4_ratio), ${param.tap4_gain}\n \n ; Tap 3\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t3_ratio), ${param.tap3_gain}\n \n ; Tap 2\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t2_ratio), ${param.tap2_gain}\n \n ; Tap 1\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t1_ratio), ${param.tap1_gain}\n @endif\n \n ; 4. Export Final Mix\n wrax ${output.mix}, 0.0",
|
|
810
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.delay.mn3011\",\n \"name\": \"MN3011 Multitap BBD Delay\",\n \"category\": \"Effects\",\n \"subcategory\": \"Delay\",\n \"description\": \"Simulation of the classic MN3011 mult-tap BBD delay chip\",\n \"color\": \"#6060c4\",\n \"width\": 230,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Audio In\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"fb_in\",\n \"name\": \"Feedback\",\n \"type\": \"audio\",\n \"required\": false\n },\n {\n \"id\": \"time_cv\",\n \"name\": \"Delay Time\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"time\"\n },\n {\n \"id\": \"fb_level_cv\",\n \"name\": \"Feedback Level\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"fb_level\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"mix\",\n \"name\": \"Mix Out\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"tap6\",\n \"name\": \"Tap 6 Out\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"input_gain\",\n \"name\": \"Input Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\",\n \"description\": \"Gain of the dry signal entering the delay line.\"\n },\n {\n \"id\": \"fb_level\",\n \"name\": \"Feedback Level\",\n \"type\": \"number\",\n \"min\": 0,\n \"max\": 1,\n \"default\": 0.5,\n \"step\": 0.01,\n \"description\": \"Amount of feedback signal mixed in.\"\n },\n {\n \"id\": \"fbk_gain\",\n \"name\": \"Feedback Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\",\n \"description\": \"Master gain coefficient for the feedback loop.\"\n },\n {\n \"id\": \"time\",\n \"name\": \"Delay Time (Scaling)\",\n \"type\": \"number\",\n \"min\": 0,\n \"max\": 1,\n \"default\": 1.0,\n \"step\": 0.01,\n \"description\": \"Global time scaling for all BBD taps (simulates clock rate).\"\n },\n {\n \"id\": \"max_delay\",\n \"name\": \"Max BBD Clock (ms)\",\n \"type\": \"number\",\n \"min\": 1,\n \"max\": 1000,\n \"default\": 1000,\n \"conversion\": \"LENGTHTOTIME\",\n \"description\": \"Maximum possible delay of the longest tap (3328 stages).\"\n },\n {\n \"id\": \"tap1_gain\",\n \"name\": \"Tap 1 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"tap2_gain\",\n \"name\": \"Tap 2 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"tap3_gain\",\n \"name\": \"Tap 3 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"tap4_gain\",\n \"name\": \"Tap 4 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"tap5_gain\",\n \"name\": \"Tap 5 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"tap6_gain\",\n \"name\": \"Tap 6 Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"registers\": [\n \"pot_val\",\n \"mix_acc\",\n \"tap_out\"\n ],\n \"memories\": [\n {\n \"id\": \"buffer\",\n \"size\": \"max_delay\"\n }\n ]\n}\n---\n@section header\n ; MN3011 Target Ratios (stage / 3328)\n equ t1_ratio 0.118990 ; 396/3328\n equ t2_ratio 0.198918 ; 662/3328\n equ t3_ratio 0.358774 ; 1194/3328\n equ t4_ratio 0.518630 ; 1726/3328\n equ t5_ratio 0.838341 ; 2790/3328\n equ t6_ratio 1.0 ; 3328/3328\n \n@section main\n ; 1. Feedback Processing\n @if pinConnected(fb_in)\n rdax ${input.fb_in}, 1.0\n @mulcv fb_level_cv\n sof ${param.fbk_gain}, 0.0\n @else\n clr\n @endif\n \n ; 2. Input Summing & Write\n rdax ${input.in}, ${param.input_gain}\n wra ${mem.buffer}, 0.0\n\n ; 3. Multitap Summation\n @if pinConnected(time_cv)\n ; --- Dynamic Time (ADDR_PTR mode) ---\n @cv time_cv\n wrax ${reg.pot_val}, 0.0\n \n ; Tap 6 (processed first for fb_out convenience)\n rdax ${reg.pot_val}, 1.0\n sof t6_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa 1.0\n @if pinConnected(tap6)\n wrax ${output.tap6}, 1.0\n @endif\n sof ${param.tap6_gain}, 0.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 1\n rdax ${reg.pot_val}, 1.0\n sof t1_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap1_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 2\n rdax ${reg.pot_val}, 1.0\n sof t2_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap2_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 3\n rdax ${reg.pot_val}, 1.0\n sof t3_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap3_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 4\n rdax ${reg.pot_val}, 1.0\n sof t4_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap4_gain}\n rdax ${reg.mix_acc}, 1.0\n wrax ${reg.mix_acc}, 0.0\n \n ; Tap 5\n rdax ${reg.pot_val}, 1.0\n sof t5_ratio, 0\n sof (${max_delay} / 32768.0), ((${mem.buffer} + 1) / 32768.0)\n wrax ADDR_PTR, 0\n rmpa ${param.tap5_gain}\n rdax ${reg.mix_acc}, 1.0\n \n @else\n ; --- Static Time (Fixed RDA mode) ---\n \n ; Tap 6\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t6_ratio), 1.0\n @if pinConnected(tap6)\n wrax ${output.tap6}, 1.0\n @endif\n sof ${param.tap6_gain}, 0.0\n \n ; Tap 5\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t5_ratio), ${param.tap5_gain}\n \n ; Tap 4\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t4_ratio), ${param.tap4_gain}\n \n ; Tap 3\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t3_ratio), ${param.tap3_gain}\n \n ; Tap 2\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t2_ratio), ${param.tap2_gain}\n \n ; Tap 1\n rda ${mem.buffer} + (${max_delay} * ${param.time} * t1_ratio), ${param.tap1_gain}\n @endif\n \n ; 4. Export Final Mix\n wrax ${output.mix}, 0.0"
|
|
811
811
|
},
|
|
812
812
|
{
|
|
813
813
|
"type": "effects.delay.simple",
|
|
@@ -879,8 +879,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
879
879
|
"dry",
|
|
880
880
|
"wet"
|
|
881
881
|
],
|
|
882
|
-
"template": "; Simple Delay with Mix\
|
|
883
|
-
"_rawAtl": "---\
|
|
882
|
+
"template": "; Simple Delay with Mix\n; Store dry signal and write to delay\nrdax ${input.audio_input}, 1.0\nwrax ${reg.dry}, 1.0\nwra ${mem.delayl}, 0.0\n\n; Calculate Delay Pointer (ADDR_PTR is an absolute address in delay RAM)\n@cv delay_time\n; Control sweeps from [base] to [base + size]\nsof ${delayLength}/${Fs}, (${mem.delayl} + 1)/${Fs}\nwrax ADDR_PTR, 0.0\n\n; Read wet signal\nrmpa 1.0\n\n; Mixing logic: dry + mix * (wet - dry)\nrdax ${reg.dry}, -0.999 ; ACC now equals (wet - dry)\nwrax ${reg.wet}, 0.0 ; Store wet-dry in reg.wet temporarily\n\n@cv mix_ctrl\nmulx ${reg.wet}\nrdax ${reg.dry}, 1.0\nwrax ${output.audio_output}, 0.0",
|
|
883
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.delay.simple\",\n \"name\": \"Simple Delay\",\n \"category\": \"Effects\",\n \"subcategory\": \"Delay\",\n \"description\": \"Simple delay line with variable time and mix control\",\n \"color\": \"#6060c4\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"audio_input\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"delay_time\",\n \"name\": \"Delay Time\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"delayLength\"\n },\n {\n \"id\": \"mix_ctrl\",\n \"name\": \"Mix\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"mix\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"audio_output\",\n \"name\": \"Audio Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"delayLength\",\n \"name\": \"Delay Length (ms)\",\n \"type\": \"number\",\n \"default\": 500,\n \"min\": 1,\n \"max\": 1000,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"The delay time in milliseconds. Determines the maximum possible delay time when controlled via a control signal.\",\n \"step\": 1\n },\n {\n \"id\": \"mix\",\n \"name\": \"Mix\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01,\n \"description\": \"Dry/Wet mix balance. 0.0 is pure dry, 1.0 is pure wet.\"\n }\n ],\n \"memories\": [\n {\n \"id\": \"delayl\",\n \"size\": \"delayLength\"\n }\n ],\n \"registers\": [\n \"dry\",\n \"wet\"\n ]\n}\n---\n; Simple Delay with Mix\n; Store dry signal and write to delay\nrdax ${input.audio_input}, 1.0\nwrax ${reg.dry}, 1.0\nwra ${mem.delayl}, 0.0\n\n; Calculate Delay Pointer (ADDR_PTR is an absolute address in delay RAM)\n@cv delay_time\n; Control sweeps from [base] to [base + size]\nsof ${delayLength}/${Fs}, (${mem.delayl} + 1)/${Fs}\nwrax ADDR_PTR, 0.0\n\n; Read wet signal\nrmpa 1.0\n\n; Mixing logic: dry + mix * (wet - dry)\nrdax ${reg.dry}, -0.999 ; ACC now equals (wet - dry)\nwrax ${reg.wet}, 0.0 ; Store wet-dry in reg.wet temporarily\n\n@cv mix_ctrl\nmulx ${reg.wet}\nrdax ${reg.dry}, 1.0\nwrax ${output.audio_output}, 0.0\n"
|
|
884
884
|
},
|
|
885
885
|
{
|
|
886
886
|
"type": "effects.modulation.chorus4voice",
|
|
@@ -1034,8 +1034,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1034
1034
|
"size": "${delayLength}"
|
|
1035
1035
|
}
|
|
1036
1036
|
],
|
|
1037
|
-
"template": "@section header\
|
|
1038
|
-
"_rawAtl": "---\
|
|
1037
|
+
"template": "@section header\n; Calculations for Centers:\nEQU tap1 (0.9 * ${tap1Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap2 (0.9 * ${tap2Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap3 (0.9 * ${tap3Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap4 (0.9 * ${tap4Center} * ${delayLength} + 0.05 * ${delayLength})\n\n@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Initialize LFO\nskp run, done_4voice_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_4voice_lfo:\n\n@section main\n@if pinConnected(input)\n\n; Validate LFO Rate\n@if pinConnected(rateIn)\nrdax ${input.rateIn}, (${rate} / 511.0)\nwrax ${lfoRateReg}, 0.0\n@endif\n\n; Validate LFO Width\n@if pinConnected(widthIn)\nrdax ${input.widthIn}, (${width} / 16384.0)\nwrax ${lfoRange}, 0.0\n@endif\n\n; Write input to delay line\nrdax ${input.input}, ${gain1}\nwra ${mem.delayLine}, 0.0\n\n; Voice 1: SIN, REG|COMPC\n@if pinConnected(voice1)\ncho rda, ${lfoNum}, SIN|REG|COMPC, ${mem.delayLine} + tap1\ncho rda, ${lfoNum}, SIN, ${mem.delayLine} + tap1 + 1\nwrax ${output.voice1}, 0.0\n@endif\n\n; Voice 2: SIN, REG|COMPA\n@if pinConnected(voice2)\ncho rda, ${lfoNum}, SIN|REG|COMPA, ${mem.delayLine} + tap2\ncho rda, ${lfoNum}, SIN|COMPC|COMPA, ${mem.delayLine} + tap2 + 1\nwrax ${output.voice2}, 0.0\n@endif\n\n; Voice 3: COS, REG|COMPC\n@if pinConnected(voice3)\ncho rda, ${lfoNum}, COS|REG|COMPC, ${mem.delayLine} + tap3\ncho rda, ${lfoNum}, COS, ${mem.delayLine} + tap3 + 1\nwrax ${output.voice3}, 0.0\n@endif\n\n; Voice 4: COS, REG|COMPA\n@if pinConnected(voice4)\ncho rda, ${lfoNum}, COS|REG|COMPA, ${mem.delayLine} + tap4\ncho rda, ${lfoNum}, COS|COMPC|COMPA, ${mem.delayLine} + tap4 + 1\nwrax ${output.voice4}, 0.0\n@endif\n\n@else\n; 4-Voice Chorus (no input connected)\n@endif",
|
|
1038
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.modulation.chorus4voice\",\n \"category\": \"Effects\",\n \"subcategory\": \"Modulation\",\n \"name\": \"4-Voice Chorus\",\n \"description\": \"Four-voice chorus with independent outputs\",\n \"color\": \"#24F2F2\",\n \"labelTemplate\": \"LFO ${param.lfoSel}\",\n \"inputs\": [\n { \"id\": \"input\", \"name\": \"Input\", \"type\": \"audio\", \"required\": true },\n { \"id\": \"rateIn\", \"name\": \"LFO Rate\", \"type\": \"control\", \"required\": false },\n { \"id\": \"widthIn\", \"name\": \"LFO Width\", \"type\": \"control\", \"required\": false }\n ],\n \"outputs\": [\n { \"id\": \"voice1\", \"name\": \"Voice 1\", \"type\": \"audio\" },\n { \"id\": \"voice2\", \"name\": \"Voice 2\", \"type\": \"audio\" },\n { \"id\": \"voice3\", \"name\": \"Voice 3\", \"type\": \"audio\" },\n { \"id\": \"voice4\", \"name\": \"Voice 4\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"gain1\",\n \"name\": \"Input Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"delayLength\",\n \"name\": \"Chorus Time\",\n \"type\": \"number\",\n \"default\": 15,\n \"min\": 0,\n \"max\": 50,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"Delay time in ms.\",\n \"step\": 1\n },\n {\n \"id\": \"tap1Center\",\n \"name\": \"Tap 1 Center\",\n \"type\": \"number\",\n \"default\": 0.25,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.001\n },\n {\n \"id\": \"tap2Center\",\n \"name\": \"Tap 2 Center\",\n \"type\": \"number\",\n \"default\": 0.33,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.001\n },\n {\n \"id\": \"tap3Center\",\n \"name\": \"Tap 3 Center\",\n \"type\": \"number\",\n \"default\": 0.63,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.001\n },\n {\n \"id\": \"tap4Center\",\n \"name\": \"Tap 4 Center\",\n \"type\": \"number\",\n \"default\": 0.75,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.001\n },\n {\n \"id\": \"rate\",\n \"name\": \"LFO Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.05,\n \"max\": 10,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Frequency of the chorus modulation in Hz.\",\n \"step\": 0.01\n },\n {\n \"id\": \"width\",\n \"name\": \"LFO Width (ms)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 20,\n \"conversion\": \"MS_TO_LFO_RANGE\",\n \"description\": \"The width of modulation in ms.\",\n \"step\": 0.1\n },\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Select\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"label\": \"LFO 0\", \"value\": 0 },\n { \"label\": \"LFO 1\", \"value\": 1 }\n ]\n }\n ],\n \"memories\": [\n { \"id\": \"delayLine\", \"size\": \"${delayLength}\" }\n ]\n}\n---\n@section header\n; Calculations for Centers:\nEQU tap1 (0.9 * ${tap1Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap2 (0.9 * ${tap2Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap3 (0.9 * ${tap3Center} * ${delayLength} + 0.05 * ${delayLength})\nEQU tap4 (0.9 * ${tap4Center} * ${delayLength} + 0.05 * ${delayLength})\n\n@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Initialize LFO\nskp run, done_4voice_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_4voice_lfo:\n\n@section main\n@if pinConnected(input)\n\n; Validate LFO Rate\n@if pinConnected(rateIn)\nrdax ${input.rateIn}, (${rate} / 511.0)\nwrax ${lfoRateReg}, 0.0\n@endif\n\n; Validate LFO Width\n@if pinConnected(widthIn)\nrdax ${input.widthIn}, (${width} / 16384.0)\nwrax ${lfoRange}, 0.0\n@endif\n\n; Write input to delay line\nrdax ${input.input}, ${gain1}\nwra ${mem.delayLine}, 0.0\n\n; Voice 1: SIN, REG|COMPC\n@if pinConnected(voice1)\ncho rda, ${lfoNum}, SIN|REG|COMPC, ${mem.delayLine} + tap1\ncho rda, ${lfoNum}, SIN, ${mem.delayLine} + tap1 + 1\nwrax ${output.voice1}, 0.0\n@endif\n\n; Voice 2: SIN, REG|COMPA\n@if pinConnected(voice2)\ncho rda, ${lfoNum}, SIN|REG|COMPA, ${mem.delayLine} + tap2\ncho rda, ${lfoNum}, SIN|COMPC|COMPA, ${mem.delayLine} + tap2 + 1\nwrax ${output.voice2}, 0.0\n@endif\n\n; Voice 3: COS, REG|COMPC\n@if pinConnected(voice3)\ncho rda, ${lfoNum}, COS|REG|COMPC, ${mem.delayLine} + tap3\ncho rda, ${lfoNum}, COS, ${mem.delayLine} + tap3 + 1\nwrax ${output.voice3}, 0.0\n@endif\n\n; Voice 4: COS, REG|COMPA\n@if pinConnected(voice4)\ncho rda, ${lfoNum}, COS|REG|COMPA, ${mem.delayLine} + tap4\ncho rda, ${lfoNum}, COS|COMPC|COMPA, ${mem.delayLine} + tap4 + 1\nwrax ${output.voice4}, 0.0\n@endif\n\n@else\n; 4-Voice Chorus (no input connected)\n@endif\n"
|
|
1039
1039
|
},
|
|
1040
1040
|
{
|
|
1041
1041
|
"type": "effects.modulation.flanger",
|
|
@@ -1166,8 +1166,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1166
1166
|
"size": 1024
|
|
1167
1167
|
}
|
|
1168
1168
|
],
|
|
1169
|
-
"template": "@if isequalto lfoSel 0\
|
|
1170
|
-
"_rawAtl": "---\
|
|
1169
|
+
"template": "@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Flanger LFO init\nskp run, done_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_lfo:\n\n@section main\n; Flanger\n@if pinConnected(rateIn)\nrdax ${input.rateIn}, ${param.rate.max} / 511.0\nsof 1.0, ${param.rate.min} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n@if pinConnected(widthIn)\nrdax ${input.widthIn}, ${param.width.max} / 32767.0\nsof 1.0, ${param.width.min} / 32767.0\nwrax ${lfoRange}, 0.0\n@endif\n\n@if pinConnected(feedbackIn)\nrdax ${input.feedbackIn}, ${fbkGain}\n@if pinConnected(fbk)\nmulx ${input.fbk}\n@endif\n@endif\n\nrdax ${input.input}, ${inputGain}\nwra ${mem.delayl}, 0.0\n\n; tapCenter\n@equals center ${mem.delayl} + ${baseDelay}\ncho rda, ${lfoNum}, SIN | REG | COMPC, ${center}\ncho rda, ${lfoNum}, SIN, ${center} + 1\nwrax ${output.output}, 0.0\n\n@if pinConnected(tap)\n; dry/max tap\nrda ${mem.delayl} + 1023, 1.0\nwrax ${output.tap}, 0.0\n@endif",
|
|
1170
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.modulation.flanger\",\n \"name\": \"Flanger\",\n \"category\": \"Effects\",\n \"subcategory\": \"Modulation\",\n \"description\": \"Classic flanger effect with LFO modulation\",\n \"color\": \"#24F2F2\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"feedbackIn\",\n \"name\": \"Feedback In\",\n \"type\": \"audio\",\n \"required\": false\n },\n {\n \"id\": \"rateIn\",\n \"name\": \"LFO Rate\",\n \"type\": \"control\",\n \"required\": false\n },\n {\n \"id\": \"widthIn\",\n \"name\": \"LFO Width\",\n \"type\": \"control\",\n \"required\": false\n },\n {\n \"id\": \"fbk\",\n \"name\": \"Feedback Gain\",\n \"type\": \"control\",\n \"required\": false\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"tap\",\n \"name\": \"Tap\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"inputGain\",\n \"name\": \"Input Gain\",\n \"type\": \"number\",\n \"default\": 0,\n \"min\": -24,\n \"max\": 0,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n },\n {\n \"id\": \"fbkGain\",\n \"name\": \"Feedback Gain\",\n \"type\": \"number\",\n \"default\": -6,\n \"min\": -24,\n \"max\": 0,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n },\n {\n \"id\": \"baseDelay\",\n \"name\": \"Base Delay (ms)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0.1,\n \"max\": 10,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"The center point of the flange modulation in ms.\",\n \"step\": 0.1\n },\n {\n \"id\": \"rate\",\n \"name\": \"LFO Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0.05,\n \"max\": 10,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Frequency of the flange modulation in Hz.\",\n \"step\": 0.01\n },\n {\n \"id\": \"width\",\n \"name\": \"LFO Depth (ms)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 10,\n \"conversion\": \"MS_TO_LFO_RANGE\",\n \"description\": \"The depth of the flange sweep in ms.\",\n \"step\": 0.1\n },\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Select\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n {\n \"label\": \"LFO 0\",\n \"value\": 0\n },\n {\n \"label\": \"LFO 1\",\n \"value\": 1\n }\n ]\n }\n ],\n \"memories\": [\n {\n \"id\": \"delayl\",\n \"size\": 1024\n }\n ]\n}\n---\n@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Flanger LFO init\nskp run, done_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_lfo:\n\n@section main\n; Flanger\n@if pinConnected(rateIn)\nrdax ${input.rateIn}, ${param.rate.max} / 511.0\nsof 1.0, ${param.rate.min} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n@if pinConnected(widthIn)\nrdax ${input.widthIn}, ${param.width.max} / 32767.0\nsof 1.0, ${param.width.min} / 32767.0\nwrax ${lfoRange}, 0.0\n@endif\n\n@if pinConnected(feedbackIn)\nrdax ${input.feedbackIn}, ${fbkGain}\n@if pinConnected(fbk)\nmulx ${input.fbk}\n@endif\n@endif\n\nrdax ${input.input}, ${inputGain}\nwra ${mem.delayl}, 0.0\n\n; tapCenter\n@equals center ${mem.delayl} + ${baseDelay}\ncho rda, ${lfoNum}, SIN | REG | COMPC, ${center}\ncho rda, ${lfoNum}, SIN, ${center} + 1\nwrax ${output.output}, 0.0\n\n@if pinConnected(tap)\n; dry/max tap\nrda ${mem.delayl} + 1023, 1.0\nwrax ${output.tap}, 0.0\n@endif\n\n"
|
|
1171
1171
|
},
|
|
1172
1172
|
{
|
|
1173
1173
|
"type": "effects.modulation.guitar_synth",
|
|
@@ -1689,8 +1689,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1689
1689
|
"depthReg",
|
|
1690
1690
|
"wet"
|
|
1691
1691
|
],
|
|
1692
|
-
"template": "; Phaser\
|
|
1693
|
-
"_rawAtl": "---\
|
|
1692
|
+
"template": "; Phaser\n; Based on PhaserCADBlock.java\n@if ${param.lfoSel} == 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@endif\n\n\n@section init\n@if isequalto mode 0\nskp run, done_lfo\nwlds ${lfoNum}, ${param.rate}, 32767\ndone_lfo:\n@endif\n\n@section main\n@if pinConnected(audio_input)\n\n; --- Phase Coefficient Setup ---\n@if isequalto mode 0\n; Internal LFO Configuration\n@if pinConnected(lfo_speed)\nrdax ${input.lfo_speed}, ${rate} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n@if pinConnected(lfo_width)\n@cv lfo_width\nwrax ${reg.depthReg}, 0.0\n@else\nsof 0.0, ${param.depth}\nwrax ${reg.depthReg}, 0.0\n@endif\n\ncho rdal, ${lfoNum}\nsof 0.5, 0.5 ; Map -1..1 to 0..1\n; Nonlinear sweep approximation\nsof 1.0, -0.5 ; Center at 0.5\nsof 1.999, 0.0 ; Expand to -1..1\nmulx ${reg.depthReg} ; Scale by depth\nsof 0.15, 0.83 ; Map to all-pass stable range [0.83, 0.98]\nwrax ${reg.phaseReg}, 0.0\n@else\n; External Manual CV\n@cv phase_cv\nsof 0.15, 0.83 ; Map CV [0..1] to [0.83, 0.98]\nwrax ${reg.phaseReg}, 0.0\n@endif\n\n; --- All-pass Filter Chain ---\n; Use 1/64 attenuation to maintain headroom through the cascade\nrdax ${input.audio_input}, 0.015625\nwrax ${reg.temp}, 0.0 ; Input to first stage\n\n; Stage 1\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p1}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p1}, -1.0\nmulx ${reg.phaseReg}\n\n; Stage 2\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p2}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p2}, -1.0\nmulx ${reg.phaseReg}\n\n; Stage 3 & 4\n@if stages >= 2\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p3}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p3}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p4}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p4}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 5 & 6\n@if stages >= 3\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p5}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p5}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p6}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p6}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 7 & 8\n@if stages >= 4\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p7}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p7}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p8}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p8}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 9 & 10\n@if stages >= 5\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p9}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p9}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p10}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p10}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Final Stage Output Load\nrdax ${reg.temp}, 1.0\n\n; --- Gain Restoration ---\n; Restores the 1/64 attenuation (6 stages of sof -2.0)\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${reg.wet}, 1.0 ; Wet signal in wet register and ACC\n\n; --- Output Routing ---\n@if pinConnected(mix_out)\nrdax ${input.audio_input}, 1.0 ; Dry + Wet\nwrax ${output.mix_out}, 0.0\n@endif\n\n@if pinConnected(wet_out)\nrdax ${reg.wet}, 1.0\nwrax ${output.wet_out}, 0.0\n@endif\n\n@endif",
|
|
1693
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.modulation.phaser\",\n \"category\": \"Effects\",\n \"subcategory\": \"Modulation\",\n \"name\": \"Phaser\",\n \"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.\",\n \"color\": \"#00ffff\",\n \"labelTemplate\": \"${param.lfoSel == 0 ? 'SIN0' : 'SIN1'}\",\n \"inputs\": [\n {\n \"id\": \"audio_input\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"lfo_speed\",\n \"name\": \"LFO Speed\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"rate\"\n },\n {\n \"id\": \"lfo_width\",\n \"name\": \"LFO Width\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"depth\"\n },\n {\n \"id\": \"phase_cv\",\n \"name\": \"Phase CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"depth\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"mix_out\",\n \"name\": \"Mix Out\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"wet_out\",\n \"name\": \"Wet Out\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Selection\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"value\": 0, \"label\": \"SIN0\" },\n { \"value\": 1, \"label\": \"SIN1\" }\n ],\n \"description\": \"Which SIN oscillator to use (0 or 1).\"\n },\n {\n \"id\": \"rate\",\n \"name\": \"LFO Rate\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.05,\n \"max\": 10.0,\n \"step\": 0.01,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Speed of the internal SIN1 modulation LFO.\"\n },\n {\n \"id\": \"depth\",\n \"name\": \"Modulation Depth\",\n \"type\": \"number\",\n \"default\": 0.25,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Depth of the phase sweep.\"\n },\n {\n \"id\": \"stages\",\n \"name\": \"Stages\",\n \"type\": \"select\",\n \"default\": 2,\n \"options\": [\n { \"label\": \"2 Stages\", \"value\": 1 },\n { \"label\": \"4 Stages\", \"value\": 2 },\n { \"label\": \"6 Stages\", \"value\": 3 },\n { \"label\": \"8 Stages\", \"value\": 4 },\n { \"label\": \"10 Stages\", \"value\": 5 }\n ],\n \"description\": \"Number of all-pass stages. More stages create more notches in the spectrum.\"\n },\n {\n \"id\": \"mode\",\n \"name\": \"Control Mode\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"label\": \"Internal LFO\", \"value\": 0 },\n { \"label\": \"Manual / Phase CV\", \"value\": 1 }\n ],\n \"description\": \"Source of phase modulation.\"\n }\n ],\n \"registers\": [\n \"p1\", \"p2\", \"p3\", \"p4\", \"p5\", \"p6\", \"p7\", \"p8\", \"p9\", \"p10\",\n \"temp\", \"temp1\", \"phaseReg\", \"depthReg\", \"wet\"\n ]\n}\n---\n; Phaser\n; Based on PhaserCADBlock.java\n@if ${param.lfoSel} == 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@endif\n\n\n@section init\n@if isequalto mode 0\nskp run, done_lfo\nwlds ${lfoNum}, ${param.rate}, 32767\ndone_lfo:\n@endif\n\n@section main\n@if pinConnected(audio_input)\n\n; --- Phase Coefficient Setup ---\n@if isequalto mode 0\n; Internal LFO Configuration\n@if pinConnected(lfo_speed)\nrdax ${input.lfo_speed}, ${rate} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n@if pinConnected(lfo_width)\n@cv lfo_width\nwrax ${reg.depthReg}, 0.0\n@else\nsof 0.0, ${param.depth}\nwrax ${reg.depthReg}, 0.0\n@endif\n\ncho rdal, ${lfoNum}\nsof 0.5, 0.5 ; Map -1..1 to 0..1\n; Nonlinear sweep approximation\nsof 1.0, -0.5 ; Center at 0.5\nsof 1.999, 0.0 ; Expand to -1..1\nmulx ${reg.depthReg} ; Scale by depth\nsof 0.15, 0.83 ; Map to all-pass stable range [0.83, 0.98]\nwrax ${reg.phaseReg}, 0.0\n@else\n; External Manual CV\n@cv phase_cv\nsof 0.15, 0.83 ; Map CV [0..1] to [0.83, 0.98]\nwrax ${reg.phaseReg}, 0.0\n@endif\n\n; --- All-pass Filter Chain ---\n; Use 1/64 attenuation to maintain headroom through the cascade\nrdax ${input.audio_input}, 0.015625\nwrax ${reg.temp}, 0.0 ; Input to first stage\n\n; Stage 1\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p1}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p1}, -1.0\nmulx ${reg.phaseReg}\n\n; Stage 2\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p2}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p2}, -1.0\nmulx ${reg.phaseReg}\n\n; Stage 3 & 4\n@if stages >= 2\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p3}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p3}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p4}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p4}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 5 & 6\n@if stages >= 3\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p5}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p5}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p6}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p6}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 7 & 8\n@if stages >= 4\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p7}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p7}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p8}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p8}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Stage 9 & 10\n@if stages >= 5\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p9}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p9}, -1.0\nmulx ${reg.phaseReg}\n\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp1}, 0.0\nrdax ${reg.p10}, 1.0\nwrax ${reg.temp}, 1.0\nmulx ${reg.phaseReg}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.p10}, -1.0\nmulx ${reg.phaseReg}\n@endif\n\n; Final Stage Output Load\nrdax ${reg.temp}, 1.0\n\n; --- Gain Restoration ---\n; Restores the 1/64 attenuation (6 stages of sof -2.0)\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${reg.wet}, 1.0 ; Wet signal in wet register and ACC\n\n; --- Output Routing ---\n@if pinConnected(mix_out)\nrdax ${input.audio_input}, 1.0 ; Dry + Wet\nwrax ${output.mix_out}, 0.0\n@endif\n\n@if pinConnected(wet_out)\nrdax ${reg.wet}, 1.0\nwrax ${output.wet_out}, 0.0\n@endif\n\n@endif"
|
|
1694
1694
|
},
|
|
1695
1695
|
{
|
|
1696
1696
|
"type": "effects.novelty.chiptune",
|
|
@@ -1834,8 +1834,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1834
1834
|
"wet",
|
|
1835
1835
|
"mix_val"
|
|
1836
1836
|
],
|
|
1837
|
-
"template": "@section header\
|
|
1838
|
-
"_rawAtl": "---\r\n{\r\n \"type\": \"effects.novelty.chiptune\",\r\n \"name\": \"Chip Tune\",\r\n \"category\": \"Effects\",\r\n \"subcategory\": \"Lo-Fi\",\r\n \"description\": \"Commodore 64 SID chip emulator: Transforms your guitar into 8-bit chiptune glory with bit crushing, square-wave shaping, ring modulation, white noise, and the legendary SID resonant filter.\",\r\n \"color\": \"#4466BB\",\r\n \"width\": 180,\r\n \"inputs\": [\r\n {\r\n \"id\": \"in\",\r\n \"name\": \"Input\",\r\n \"type\": \"audio\",\r\n \"required\": true\r\n },\r\n {\r\n \"id\": \"crushCV\",\r\n \"name\": \"Crush\",\r\n \"type\": \"control\",\r\n \"required\": false,\r\n \"parameter\": \"crush\"\r\n },\r\n {\r\n \"id\": \"squareCV\",\r\n \"name\": \"Square\",\r\n \"type\": \"control\",\r\n \"required\": false,\r\n \"parameter\": \"square\"\r\n },\r\n {\r\n \"id\": \"cutoffCV\",\r\n \"name\": \"Cutoff\",\r\n \"type\": \"control\",\r\n \"required\": false,\r\n \"parameter\": \"cutoff\"\r\n },\r\n {\r\n \"id\": \"resoCV\",\r\n \"name\": \"Resonance\",\r\n \"type\": \"control\",\r\n \"required\": false,\r\n \"parameter\": \"resonance\"\r\n }\r\n ],\r\n \"outputs\": [\r\n {\r\n \"id\": \"out\",\r\n \"name\": \"Output\",\r\n \"type\": \"audio\"\r\n }\r\n ],\r\n \"parameters\": [\r\n {\r\n \"id\": \"crush\",\r\n \"name\": \"Crush Depth\",\r\n \"type\": \"number\",\r\n \"default\": 0.2,\r\n \"min\": 0.005,\r\n \"max\": 0.25,\r\n \"step\": 0.005,\r\n \"description\": \"Sample-rate reduction intensity. Higher = more lo-fi 8-bit crunch.\"\r\n },\r\n {\r\n \"id\": \"square\",\r\n \"name\": \"Square Drive\",\r\n \"type\": \"number\",\r\n \"default\": 0.5,\r\n \"min\": 0.0,\r\n \"max\": 1.99,\r\n \"step\": 0.01,\r\n \"description\": \"Blend from clean (0) to hard-clipped square pulse waveform (max).\"\r\n },\r\n {\r\n \"id\": \"ring_freq\",\r\n \"name\": \"Ring Mod\",\r\n \"type\": \"number\",\r\n \"default\": 0.0,\r\n \"min\": 0.0,\r\n \"max\": 1.0,\r\n \"step\": 0.01,\r\n \"description\": \"Ring modulator frequency. 0 = off. Adds metallic SID harmonics.\"\r\n },\r\n {\r\n \"id\": \"noise\",\r\n \"name\": \"Noise Level\",\r\n \"type\": \"number\",\r\n \"default\": 0.5,\r\n \"min\": 0.0,\r\n \"max\": 1.0,\r\n \"step\": 0.01,\r\n \"description\": \"White noise generator level. Classic SID noise channel for hi-hats, snares, and static textures.\"\r\n },\r\n {\r\n \"id\": \"cutoff\",\r\n \"name\": \"Filter Cutoff\",\r\n \"type\": \"number\",\r\n \"default\": 3000,\r\n \"min\": 60,\r\n \"max\": 6000,\r\n \"step\": 10,\r\n \"conversion\": \"SVFFREQ\",\r\n \"description\": \"SID-style resonant low-pass filter cutoff frequency.\"\r\n },\r\n {\r\n \"id\": \"resonance\",\r\n \"name\": \"Filter Resonance\",\r\n \"type\": \"number\",\r\n \"default\": 4.0,\r\n \"min\": 0.5,\r\n \"max\": 20.0,\r\n \"step\": 0.1,\r\n \"conversion\": \"SVF_DAMP\",\r\n \"description\": \"Filter Q. Crank it for that classic SID filter sweep character.\"\r\n },\r\n {\r\n \"id\": \"mix\",\r\n \"name\": \"Dry/Wet Mix\",\r\n \"type\": \"number\",\r\n \"default\": 1.0,\r\n \"min\": 0.0,\r\n \"max\": 1.0,\r\n \"step\": 0.01,\r\n \"description\": \"Blend between dry and SID-processed signal.\"\r\n }\r\n ],\r\n \"registers\": [\r\n \"counter\",\r\n \"held\",\r\n \"squared\",\r\n \"ring_sin\",\r\n \"ring_cos\",\r\n \"f_ring\",\r\n \"ringmod\",\r\n \"noise_reg\",\r\n \"noise_dc\",\r\n \"lp_state\",\r\n \"bp_state\",\r\n \"damp_reg\",\r\n \"dry\",\r\n \"wet\",\r\n \"mix_val\"\r\n ]\r\n}\r\n---\r\n@section header\r\n equ damp_target (${param.resonance})\r\n\r\n@section init\r\n ; Seed the ring mod oscillator (cos=0.5, sin=0)\r\n ; Without this, the magic circle stays at zero forever!\r\n sof 0.0, 0.5\r\n wrax ${reg.ring_cos}, 0.0\r\n\r\n ; Seed the noise LFSR with a non-zero, non-one starting value\r\n sof 0.0, 0.3\r\n wrax ${reg.noise_reg}, 0.0\r\n\r\n@section main\r\n @if pinConnected(in)\r\n\r\n ; ======================================================\r\n ; Stage 0: Save dry signal for mix\r\n ; ======================================================\r\n rdax ${input.in}, 1.0\r\n wrax ${reg.dry}, 0.0\r\n\r\n ; ======================================================\r\n ; Stage 1: Sample-Rate Reduction (SID S&H Bit Crush)\r\n ; ======================================================\r\n skp run, ${local.SKIP_INIT}\r\n rdax ${input.in}, 1.0\r\n wrax ${reg.held}, 0.0\r\n ${local.SKIP_INIT}:\r\n\r\n ; Counter increment: inverted crush so higher = more crushed\r\n ; step = 0.255 - crush_value (smaller step = slower S&H = more lo-fi)\r\n rdax ${reg.counter}, 1.0\r\n wrax ${reg.counter}, 0.0\r\n @cv crushCV ; ACC = crush depth (0.005..0.25)\r\n sof -1.0, 0.255 ; ACC = 0.255 - crush = step size\r\n rdax ${reg.counter}, 1.0 ; ACC = counter + step\r\n wrax ${reg.counter}, 1.0\r\n\r\n sof 1.0, -0.99\r\n skp neg, ${local.SKIP_SAMPLE}\r\n\r\n clr\r\n rdax ${input.in}, 1.0\r\n wrax ${reg.held}, 0.0\r\n sof 0.0, 0.0\r\n wrax ${reg.counter}, 0.0\r\n\r\n ${local.SKIP_SAMPLE}:\r\n\r\n ; ======================================================\r\n ; Stage 2: Square Wave Shaping (SID Pulse Oscillator)\r\n ; ======================================================\r\n clr\r\n rdax ${reg.held}, 1.0\r\n sof 1.99, 0.0\r\n sof -1.99, 0.0\r\n sof -1.99, 0.0\r\n sof 0.5, 0.0\r\n wrax ${reg.squared}, 0.0\r\n\r\n ; Crossfade: out = held + (squared - held) * squareDrive\r\n rdax ${reg.squared}, 1.0\r\n rdax ${reg.held}, -1.0\r\n wrax ${reg.mix_val}, 0.0 ; Save (squared - held), clear ACC\r\n @cv squareCV ; ACC = square drive value\r\n mulx ${reg.mix_val} ; ACC = (squared - held) * drive\r\n rdax ${reg.held}, 1.0 ; ACC = held + (squared - held) * drive\r\n wrax ${reg.squared}, 0.0\r\n\r\n ; ======================================================\r\n ; Stage 3: Ring Modulation (SID Ring Mod)\r\n ; ======================================================\r\n sof 0.0, ${param.ring_freq}\r\n sof 0.15, 0.0\r\n wrax ${reg.f_ring}, 0.0\r\n\r\n ; Magic circle sine oscillator (seeded in init!)\r\n rdax ${reg.ring_sin}, -1.0\r\n mulx ${reg.f_ring}\r\n rdax ${reg.ring_cos}, 1.0\r\n wrax ${reg.ring_cos}, 1.0\r\n mulx ${reg.f_ring}\r\n rdax ${reg.ring_sin}, 1.0\r\n wrax ${reg.ring_sin}, 0.0\r\n\r\n ; Ring mod = squared * carrier\r\n rdax ${reg.squared}, 1.0\r\n mulx ${reg.ring_sin}\r\n sof 1.99, 0.0\r\n wrax ${reg.ringmod}, 0.0\r\n\r\n ; Crossfade by ring_freq: 0 = all squared, 1 = all ring\r\n sof 0.0, ${param.ring_freq}\r\n wrax ${reg.mix_val}, 0.0\r\n rdax ${reg.ringmod}, 1.0\r\n rdax ${reg.squared}, -1.0\r\n mulx ${reg.mix_val}\r\n rdax ${reg.squared}, 1.0\r\n wrax ${reg.wet}, 0.0\r\n\r\n ; ======================================================\r\n ; Stage 3.5: SID Noise Channel (Tent Map + DC Blocker)\r\n ; ======================================================\r\n ; Tent map: x_next ≈ 1 - 2|x| (chaotic noise source)\r\n ; FV-1 can't represent exact coefficients 2/1, so the raw\r\n ; output has a slight positive mean. A DC-blocking LP filter\r\n ; tracks and removes it for guaranteed zero-mean noise.\r\n rdax ${reg.noise_reg}, 1.0 ; ACC = x\r\n absa ; ACC = |x|\r\n sof -1.99, 0.999 ; ACC ≈ 1 - 2|x| — tent map\r\n wrax ${reg.noise_reg}, 0.0 ; Save x_next, ACC = 0\r\n\r\n ; DC blocker: track running average with ultra-slow LP\r\n rdax ${reg.noise_dc}, 1.0 ; ACC = old DC estimate\r\n rdfx ${reg.noise_reg}, 0.001 ; ACC = DC_old*0.999 + noise*0.001\r\n wrax ${reg.noise_dc}, -1.0 ; Save new DC estimate, ACC = -DC\r\n rdax ${reg.noise_reg}, 1.0 ; ACC = noise - DC = zero-mean noise\r\n\r\n ; Scale by noise level and add to wet signal\r\n ; Noise needs ~12dB pre-boost because the SID filter downstream\r\n ; heavily attenuates high-frequency content where most noise energy lives\r\n sof 1.99, 0.0\r\n sof 1.99, 0.0\r\n sof ${param.noise}, 0.0\r\n rdax ${reg.wet}, 1.0\r\n wrax ${reg.wet}, 0.0\r\n\r\n ; ======================================================\r\n ; Stage 4: SID Filter (Resonant SVF Low-Pass)\r\n ; ======================================================\r\n ; Load damping coefficient (resonance CV or fixed parameter)\r\n @cv resoCV\r\n wrax ${reg.damp_reg}, 0.0\r\n\r\n ; Load cutoff coefficient\r\n @cv cutoffCV\r\n wrax ${reg.mix_val}, 0.0\r\n\r\n ; Chamberlin SVF: HP → BP → LP\r\n rdax ${reg.wet}, 1.0\r\n rdax ${reg.lp_state}, -1.0\r\n wrax ${reg.wet}, 0.0 ; Reuse wet as temp = (input - lp_old)\r\n rdax ${reg.bp_state}, 1.0\r\n mulx ${reg.damp_reg} ; ACC = bp_old * damp\r\n rdax ${reg.wet}, -1.0 ; ACC = -(input - lp_old) + bp_old * damp = -(HP)\r\n sof -1.0, 0.0 ; ACC = HP\r\n mulx ${reg.mix_val} ; ACC = F * HP\r\n rdax ${reg.bp_state}, 1.0 ; ACC = bp_old + F * HP = bp_new\r\n wrax ${reg.bp_state}, 1.0 ; Save bp, keep in ACC\r\n mulx ${reg.mix_val} ; ACC = F * bp_new\r\n rdax ${reg.lp_state}, 1.0 ; ACC = lp_old + F * bp_new = lp_new\r\n wrax ${reg.lp_state}, 0.0\r\n\r\n ; ======================================================\r\n ; Stage 5: Dry/Wet Mix\r\n ; ======================================================\r\n rdax ${reg.lp_state}, 1.0\r\n rdax ${reg.dry}, -1.0\r\n sof ${param.mix}, 0.0\r\n rdax ${reg.dry}, 1.0\r\n wrax ${output.out}, 0.0\r\n\r\n @else\r\n ; Bypassed\r\n @endif\r\n"
|
|
1837
|
+
"template": "@section header\n equ damp_target (${param.resonance})\n\n@section init\n ; Seed the ring mod oscillator (cos=0.5, sin=0)\n ; Without this, the magic circle stays at zero forever!\n sof 0.0, 0.5\n wrax ${reg.ring_cos}, 0.0\n\n ; Seed the noise LFSR with a non-zero, non-one starting value\n sof 0.0, 0.3\n wrax ${reg.noise_reg}, 0.0\n\n@section main\n @if pinConnected(in)\n\n ; ======================================================\n ; Stage 0: Save dry signal for mix\n ; ======================================================\n rdax ${input.in}, 1.0\n wrax ${reg.dry}, 0.0\n\n ; ======================================================\n ; Stage 1: Sample-Rate Reduction (SID S&H Bit Crush)\n ; ======================================================\n skp run, ${local.SKIP_INIT}\n rdax ${input.in}, 1.0\n wrax ${reg.held}, 0.0\n ${local.SKIP_INIT}:\n\n ; Counter increment: inverted crush so higher = more crushed\n ; step = 0.255 - crush_value (smaller step = slower S&H = more lo-fi)\n rdax ${reg.counter}, 1.0\n wrax ${reg.counter}, 0.0\n @cv crushCV ; ACC = crush depth (0.005..0.25)\n sof -1.0, 0.255 ; ACC = 0.255 - crush = step size\n rdax ${reg.counter}, 1.0 ; ACC = counter + step\n wrax ${reg.counter}, 1.0\n\n sof 1.0, -0.99\n skp neg, ${local.SKIP_SAMPLE}\n\n clr\n rdax ${input.in}, 1.0\n wrax ${reg.held}, 0.0\n sof 0.0, 0.0\n wrax ${reg.counter}, 0.0\n\n ${local.SKIP_SAMPLE}:\n\n ; ======================================================\n ; Stage 2: Square Wave Shaping (SID Pulse Oscillator)\n ; ======================================================\n clr\n rdax ${reg.held}, 1.0\n sof 1.99, 0.0\n sof -1.99, 0.0\n sof -1.99, 0.0\n sof 0.5, 0.0\n wrax ${reg.squared}, 0.0\n\n ; Crossfade: out = held + (squared - held) * squareDrive\n rdax ${reg.squared}, 1.0\n rdax ${reg.held}, -1.0\n wrax ${reg.mix_val}, 0.0 ; Save (squared - held), clear ACC\n @cv squareCV ; ACC = square drive value\n mulx ${reg.mix_val} ; ACC = (squared - held) * drive\n rdax ${reg.held}, 1.0 ; ACC = held + (squared - held) * drive\n wrax ${reg.squared}, 0.0\n\n ; ======================================================\n ; Stage 3: Ring Modulation (SID Ring Mod)\n ; ======================================================\n sof 0.0, ${param.ring_freq}\n sof 0.15, 0.0\n wrax ${reg.f_ring}, 0.0\n\n ; Magic circle sine oscillator (seeded in init!)\n rdax ${reg.ring_sin}, -1.0\n mulx ${reg.f_ring}\n rdax ${reg.ring_cos}, 1.0\n wrax ${reg.ring_cos}, 1.0\n mulx ${reg.f_ring}\n rdax ${reg.ring_sin}, 1.0\n wrax ${reg.ring_sin}, 0.0\n\n ; Ring mod = squared * carrier\n rdax ${reg.squared}, 1.0\n mulx ${reg.ring_sin}\n sof 1.99, 0.0\n wrax ${reg.ringmod}, 0.0\n\n ; Crossfade by ring_freq: 0 = all squared, 1 = all ring\n sof 0.0, ${param.ring_freq}\n wrax ${reg.mix_val}, 0.0\n rdax ${reg.ringmod}, 1.0\n rdax ${reg.squared}, -1.0\n mulx ${reg.mix_val}\n rdax ${reg.squared}, 1.0\n wrax ${reg.wet}, 0.0\n\n ; ======================================================\n ; Stage 3.5: SID Noise Channel (Tent Map + DC Blocker)\n ; ======================================================\n ; Tent map: x_next ≈ 1 - 2|x| (chaotic noise source)\n ; FV-1 can't represent exact coefficients 2/1, so the raw\n ; output has a slight positive mean. A DC-blocking LP filter\n ; tracks and removes it for guaranteed zero-mean noise.\n rdax ${reg.noise_reg}, 1.0 ; ACC = x\n absa ; ACC = |x|\n sof -1.99, 0.999 ; ACC ≈ 1 - 2|x| — tent map\n wrax ${reg.noise_reg}, 0.0 ; Save x_next, ACC = 0\n\n ; DC blocker: track running average with ultra-slow LP\n rdax ${reg.noise_dc}, 1.0 ; ACC = old DC estimate\n rdfx ${reg.noise_reg}, 0.001 ; ACC = DC_old*0.999 + noise*0.001\n wrax ${reg.noise_dc}, -1.0 ; Save new DC estimate, ACC = -DC\n rdax ${reg.noise_reg}, 1.0 ; ACC = noise - DC = zero-mean noise\n\n ; Scale by noise level and add to wet signal\n ; Noise needs ~12dB pre-boost because the SID filter downstream\n ; heavily attenuates high-frequency content where most noise energy lives\n sof 1.99, 0.0\n sof 1.99, 0.0\n sof ${param.noise}, 0.0\n rdax ${reg.wet}, 1.0\n wrax ${reg.wet}, 0.0\n\n ; ======================================================\n ; Stage 4: SID Filter (Resonant SVF Low-Pass)\n ; ======================================================\n ; Load damping coefficient (resonance CV or fixed parameter)\n @cv resoCV\n wrax ${reg.damp_reg}, 0.0\n\n ; Load cutoff coefficient\n @cv cutoffCV\n wrax ${reg.mix_val}, 0.0\n\n ; Chamberlin SVF: HP → BP → LP\n rdax ${reg.wet}, 1.0\n rdax ${reg.lp_state}, -1.0\n wrax ${reg.wet}, 0.0 ; Reuse wet as temp = (input - lp_old)\n rdax ${reg.bp_state}, 1.0\n mulx ${reg.damp_reg} ; ACC = bp_old * damp\n rdax ${reg.wet}, -1.0 ; ACC = -(input - lp_old) + bp_old * damp = -(HP)\n sof -1.0, 0.0 ; ACC = HP\n mulx ${reg.mix_val} ; ACC = F * HP\n rdax ${reg.bp_state}, 1.0 ; ACC = bp_old + F * HP = bp_new\n wrax ${reg.bp_state}, 1.0 ; Save bp, keep in ACC\n mulx ${reg.mix_val} ; ACC = F * bp_new\n rdax ${reg.lp_state}, 1.0 ; ACC = lp_old + F * bp_new = lp_new\n wrax ${reg.lp_state}, 0.0\n\n ; ======================================================\n ; Stage 5: Dry/Wet Mix\n ; ======================================================\n rdax ${reg.lp_state}, 1.0\n rdax ${reg.dry}, -1.0\n sof ${param.mix}, 0.0\n rdax ${reg.dry}, 1.0\n wrax ${output.out}, 0.0\n\n @else\n ; Bypassed\n @endif",
|
|
1838
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.novelty.chiptune\",\n \"name\": \"Chip Tune\",\n \"category\": \"Effects\",\n \"subcategory\": \"Lo-Fi\",\n \"description\": \"Commodore 64 SID chip emulator: Transforms your guitar into 8-bit chiptune glory with bit crushing, square-wave shaping, ring modulation, white noise, and the legendary SID resonant filter.\",\n \"color\": \"#4466BB\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"crushCV\",\n \"name\": \"Crush\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"crush\"\n },\n {\n \"id\": \"squareCV\",\n \"name\": \"Square\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"square\"\n },\n {\n \"id\": \"cutoffCV\",\n \"name\": \"Cutoff\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"cutoff\"\n },\n {\n \"id\": \"resoCV\",\n \"name\": \"Resonance\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"resonance\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"crush\",\n \"name\": \"Crush Depth\",\n \"type\": \"number\",\n \"default\": 0.2,\n \"min\": 0.005,\n \"max\": 0.25,\n \"step\": 0.005,\n \"description\": \"Sample-rate reduction intensity. Higher = more lo-fi 8-bit crunch.\"\n },\n {\n \"id\": \"square\",\n \"name\": \"Square Drive\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.99,\n \"step\": 0.01,\n \"description\": \"Blend from clean (0) to hard-clipped square pulse waveform (max).\"\n },\n {\n \"id\": \"ring_freq\",\n \"name\": \"Ring Mod\",\n \"type\": \"number\",\n \"default\": 0.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Ring modulator frequency. 0 = off. Adds metallic SID harmonics.\"\n },\n {\n \"id\": \"noise\",\n \"name\": \"Noise Level\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"White noise generator level. Classic SID noise channel for hi-hats, snares, and static textures.\"\n },\n {\n \"id\": \"cutoff\",\n \"name\": \"Filter Cutoff\",\n \"type\": \"number\",\n \"default\": 3000,\n \"min\": 60,\n \"max\": 6000,\n \"step\": 10,\n \"conversion\": \"SVFFREQ\",\n \"description\": \"SID-style resonant low-pass filter cutoff frequency.\"\n },\n {\n \"id\": \"resonance\",\n \"name\": \"Filter Resonance\",\n \"type\": \"number\",\n \"default\": 4.0,\n \"min\": 0.5,\n \"max\": 20.0,\n \"step\": 0.1,\n \"conversion\": \"SVF_DAMP\",\n \"description\": \"Filter Q. Crank it for that classic SID filter sweep character.\"\n },\n {\n \"id\": \"mix\",\n \"name\": \"Dry/Wet Mix\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Blend between dry and SID-processed signal.\"\n }\n ],\n \"registers\": [\n \"counter\",\n \"held\",\n \"squared\",\n \"ring_sin\",\n \"ring_cos\",\n \"f_ring\",\n \"ringmod\",\n \"noise_reg\",\n \"noise_dc\",\n \"lp_state\",\n \"bp_state\",\n \"damp_reg\",\n \"dry\",\n \"wet\",\n \"mix_val\"\n ]\n}\n---\n@section header\n equ damp_target (${param.resonance})\n\n@section init\n ; Seed the ring mod oscillator (cos=0.5, sin=0)\n ; Without this, the magic circle stays at zero forever!\n sof 0.0, 0.5\n wrax ${reg.ring_cos}, 0.0\n\n ; Seed the noise LFSR with a non-zero, non-one starting value\n sof 0.0, 0.3\n wrax ${reg.noise_reg}, 0.0\n\n@section main\n @if pinConnected(in)\n\n ; ======================================================\n ; Stage 0: Save dry signal for mix\n ; ======================================================\n rdax ${input.in}, 1.0\n wrax ${reg.dry}, 0.0\n\n ; ======================================================\n ; Stage 1: Sample-Rate Reduction (SID S&H Bit Crush)\n ; ======================================================\n skp run, ${local.SKIP_INIT}\n rdax ${input.in}, 1.0\n wrax ${reg.held}, 0.0\n ${local.SKIP_INIT}:\n\n ; Counter increment: inverted crush so higher = more crushed\n ; step = 0.255 - crush_value (smaller step = slower S&H = more lo-fi)\n rdax ${reg.counter}, 1.0\n wrax ${reg.counter}, 0.0\n @cv crushCV ; ACC = crush depth (0.005..0.25)\n sof -1.0, 0.255 ; ACC = 0.255 - crush = step size\n rdax ${reg.counter}, 1.0 ; ACC = counter + step\n wrax ${reg.counter}, 1.0\n\n sof 1.0, -0.99\n skp neg, ${local.SKIP_SAMPLE}\n\n clr\n rdax ${input.in}, 1.0\n wrax ${reg.held}, 0.0\n sof 0.0, 0.0\n wrax ${reg.counter}, 0.0\n\n ${local.SKIP_SAMPLE}:\n\n ; ======================================================\n ; Stage 2: Square Wave Shaping (SID Pulse Oscillator)\n ; ======================================================\n clr\n rdax ${reg.held}, 1.0\n sof 1.99, 0.0\n sof -1.99, 0.0\n sof -1.99, 0.0\n sof 0.5, 0.0\n wrax ${reg.squared}, 0.0\n\n ; Crossfade: out = held + (squared - held) * squareDrive\n rdax ${reg.squared}, 1.0\n rdax ${reg.held}, -1.0\n wrax ${reg.mix_val}, 0.0 ; Save (squared - held), clear ACC\n @cv squareCV ; ACC = square drive value\n mulx ${reg.mix_val} ; ACC = (squared - held) * drive\n rdax ${reg.held}, 1.0 ; ACC = held + (squared - held) * drive\n wrax ${reg.squared}, 0.0\n\n ; ======================================================\n ; Stage 3: Ring Modulation (SID Ring Mod)\n ; ======================================================\n sof 0.0, ${param.ring_freq}\n sof 0.15, 0.0\n wrax ${reg.f_ring}, 0.0\n\n ; Magic circle sine oscillator (seeded in init!)\n rdax ${reg.ring_sin}, -1.0\n mulx ${reg.f_ring}\n rdax ${reg.ring_cos}, 1.0\n wrax ${reg.ring_cos}, 1.0\n mulx ${reg.f_ring}\n rdax ${reg.ring_sin}, 1.0\n wrax ${reg.ring_sin}, 0.0\n\n ; Ring mod = squared * carrier\n rdax ${reg.squared}, 1.0\n mulx ${reg.ring_sin}\n sof 1.99, 0.0\n wrax ${reg.ringmod}, 0.0\n\n ; Crossfade by ring_freq: 0 = all squared, 1 = all ring\n sof 0.0, ${param.ring_freq}\n wrax ${reg.mix_val}, 0.0\n rdax ${reg.ringmod}, 1.0\n rdax ${reg.squared}, -1.0\n mulx ${reg.mix_val}\n rdax ${reg.squared}, 1.0\n wrax ${reg.wet}, 0.0\n\n ; ======================================================\n ; Stage 3.5: SID Noise Channel (Tent Map + DC Blocker)\n ; ======================================================\n ; Tent map: x_next ≈ 1 - 2|x| (chaotic noise source)\n ; FV-1 can't represent exact coefficients 2/1, so the raw\n ; output has a slight positive mean. A DC-blocking LP filter\n ; tracks and removes it for guaranteed zero-mean noise.\n rdax ${reg.noise_reg}, 1.0 ; ACC = x\n absa ; ACC = |x|\n sof -1.99, 0.999 ; ACC ≈ 1 - 2|x| — tent map\n wrax ${reg.noise_reg}, 0.0 ; Save x_next, ACC = 0\n\n ; DC blocker: track running average with ultra-slow LP\n rdax ${reg.noise_dc}, 1.0 ; ACC = old DC estimate\n rdfx ${reg.noise_reg}, 0.001 ; ACC = DC_old*0.999 + noise*0.001\n wrax ${reg.noise_dc}, -1.0 ; Save new DC estimate, ACC = -DC\n rdax ${reg.noise_reg}, 1.0 ; ACC = noise - DC = zero-mean noise\n\n ; Scale by noise level and add to wet signal\n ; Noise needs ~12dB pre-boost because the SID filter downstream\n ; heavily attenuates high-frequency content where most noise energy lives\n sof 1.99, 0.0\n sof 1.99, 0.0\n sof ${param.noise}, 0.0\n rdax ${reg.wet}, 1.0\n wrax ${reg.wet}, 0.0\n\n ; ======================================================\n ; Stage 4: SID Filter (Resonant SVF Low-Pass)\n ; ======================================================\n ; Load damping coefficient (resonance CV or fixed parameter)\n @cv resoCV\n wrax ${reg.damp_reg}, 0.0\n\n ; Load cutoff coefficient\n @cv cutoffCV\n wrax ${reg.mix_val}, 0.0\n\n ; Chamberlin SVF: HP → BP → LP\n rdax ${reg.wet}, 1.0\n rdax ${reg.lp_state}, -1.0\n wrax ${reg.wet}, 0.0 ; Reuse wet as temp = (input - lp_old)\n rdax ${reg.bp_state}, 1.0\n mulx ${reg.damp_reg} ; ACC = bp_old * damp\n rdax ${reg.wet}, -1.0 ; ACC = -(input - lp_old) + bp_old * damp = -(HP)\n sof -1.0, 0.0 ; ACC = HP\n mulx ${reg.mix_val} ; ACC = F * HP\n rdax ${reg.bp_state}, 1.0 ; ACC = bp_old + F * HP = bp_new\n wrax ${reg.bp_state}, 1.0 ; Save bp, keep in ACC\n mulx ${reg.mix_val} ; ACC = F * bp_new\n rdax ${reg.lp_state}, 1.0 ; ACC = lp_old + F * bp_new = lp_new\n wrax ${reg.lp_state}, 0.0\n\n ; ======================================================\n ; Stage 5: Dry/Wet Mix\n ; ======================================================\n rdax ${reg.lp_state}, 1.0\n rdax ${reg.dry}, -1.0\n sof ${param.mix}, 0.0\n rdax ${reg.dry}, 1.0\n wrax ${output.out}, 0.0\n\n @else\n ; Bypassed\n @endif\n"
|
|
1839
1839
|
},
|
|
1840
1840
|
{
|
|
1841
1841
|
"type": "effects.pitch.octave_up_down",
|
|
@@ -1876,8 +1876,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1876
1876
|
],
|
|
1877
1877
|
"registers": [],
|
|
1878
1878
|
"parameters": [],
|
|
1879
|
-
"template": "@section header\
|
|
1880
|
-
"_rawAtl": "---\
|
|
1879
|
+
"template": "@section header\n@equals bufferSize 4096\n\n@section init\n; Octave Up (s = 2; rate = (2-1)*16384 = 16384)\n; Octave Down (s = 0.5; rate = (0.5-1)*16384 = -8192)\nskp run, done_init\nwldr 0, -8192, ${bufferSize}\nwldr 1, 16384, ${bufferSize}\ndone_init:\n\n@section main\nrdax ${input.in}, 1.0\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(octave_down)\n; Perform Octave Down (RMP0)\ncho rda, RMP0, REG | COMPC, ${mem.delayl}\ncho rda, RMP0, 0, ${mem.delayl} + 1\nwra ${mem.temp}, 0.0\ncho rda, RMP0, RPTR2 | COMPC, ${mem.delayl}\ncho rda, RMP0, RPTR2, ${mem.delayl} + 1\ncho sof, RMP0, NA | COMPC, 0.0\ncho rda, RMP0, NA, ${mem.temp}\nwrax ${output.octave_down}, 0.0\n@endif\n\n@if pinConnected(octave_up)\n; Perform Octave Up (RMP1)\ncho rda, RMP1, REG | COMPC, ${mem.delayl}\ncho rda, RMP1, 0, ${mem.delayl} + 1\nwra ${mem.temp}, 0.0\ncho rda, RMP1, RPTR2 | COMPC, ${mem.delayl}\ncho rda, RMP1, RPTR2, ${mem.delayl} + 1\ncho sof, RMP1, NA | COMPC, 0.0\ncho rda, RMP1, NA, ${mem.temp}\nwrax ${output.octave_up}, 0.0\n@endif",
|
|
1880
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.pitch.octave_up_down\",\n \"name\": \"Octave Up & Down\",\n \"category\": \"Effects\",\n \"subcategory\": \"Pitch\",\n \"description\": \"Fixed pitch shifter with both Octave Up and Octave Down outputs.\",\n \"color\": \"#fcba03\",\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n }\n ],\n \"outputs\": [\n {\n \"id\": \"octave_down\",\n \"name\": \"Octave Down\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"octave_up\",\n \"name\": \"Octave Up\",\n \"type\": \"audio\"\n }\n ],\n \"memories\": [\n {\n \"id\": \"delayl\",\n \"size\": \"bufferSize\"\n },\n {\n \"id\": \"temp\",\n \"size\": 1\n }\n ],\n \"registers\": [],\n \"parameters\": []\n}\n---\n@section header\n@equals bufferSize 4096\n\n@section init\n; Octave Up (s = 2; rate = (2-1)*16384 = 16384)\n; Octave Down (s = 0.5; rate = (0.5-1)*16384 = -8192)\nskp run, done_init\nwldr 0, -8192, ${bufferSize}\nwldr 1, 16384, ${bufferSize}\ndone_init:\n\n@section main\nrdax ${input.in}, 1.0\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(octave_down)\n; Perform Octave Down (RMP0)\ncho rda, RMP0, REG | COMPC, ${mem.delayl}\ncho rda, RMP0, 0, ${mem.delayl} + 1\nwra ${mem.temp}, 0.0\ncho rda, RMP0, RPTR2 | COMPC, ${mem.delayl}\ncho rda, RMP0, RPTR2, ${mem.delayl} + 1\ncho sof, RMP0, NA | COMPC, 0.0\ncho rda, RMP0, NA, ${mem.temp}\nwrax ${output.octave_down}, 0.0\n@endif\n\n@if pinConnected(octave_up)\n; Perform Octave Up (RMP1)\ncho rda, RMP1, REG | COMPC, ${mem.delayl}\ncho rda, RMP1, 0, ${mem.delayl} + 1\nwra ${mem.temp}, 0.0\ncho rda, RMP1, RPTR2 | COMPC, ${mem.delayl}\ncho rda, RMP1, RPTR2, ${mem.delayl} + 1\ncho sof, RMP1, NA | COMPC, 0.0\ncho rda, RMP1, NA, ${mem.temp}\nwrax ${output.octave_up}, 0.0\n@endif\n"
|
|
1881
1881
|
},
|
|
1882
1882
|
{
|
|
1883
1883
|
"type": "effects.pitch.pitch_offset",
|
|
@@ -1968,8 +1968,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
1968
1968
|
"size": 2
|
|
1969
1969
|
}
|
|
1970
1970
|
],
|
|
1971
|
-
"template": "@section header\
|
|
1972
|
-
"_rawAtl": "---\
|
|
1971
|
+
"template": "@section header\n\n@section init\n; Initialize oscillator (cosine = 1.0)\nskp run, done_init\nor $7fffff\nwrax ${reg.cososc}, 0.0\ndone_init:\n\n@section main\n; 1. Process CV and smoothing\n@cv shift_ctrl\n; ACC = Shift position (0..1, defaults to 0.5)\nrdfx ${reg.potfil}, 0.001\nwrlx ${reg.potfil}, -1.0\n; Map [0..1] to [Range/2 .. -Range/2]\n; Bipolar: (0.5 - shiftValue) * Range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0 ; Substitutes converted HZ_TO_HILBERT_SHIFT value\nwrax ${reg.shift_amount}, 0.0\n\n; 2. Audio input filtering (300Hz HPF, 3kHz LPF)\nrdax ${input.in}, 1.0\nrdfx ${reg.hpf}, 0.04\nwrhx ${reg.hpf}, -1.0\nrdfx ${reg.lpf}, 0.4\nwrlx ${reg.lpf}, -1.0\nwrax ${reg.sigfil}, 0.0039 ; Attenuate to avoid clipping in Hilbert chain\n\n; 3. All-pass phase shifter bank (Sine path)\nrda ${mem.ap1} + 1, 0.995 ; 44Hz\nwrap ${mem.ap1}, -0.995\nrda ${mem.ap2} + 1, 0.937 ; 488Hz\nwrap ${mem.ap2}, -0.937\nrda ${mem.ap3} + 1, 0.61 ; 3531Hz\nwrap ${mem.ap3}, -0.61\nwrax ${reg.sigs}, 0.0\n\n; 4. All-pass phase shifter bank (Cosine path)\nrdax ${reg.sigfil}, 0.0039 ; Match Sine path attenuation\nrda ${mem.ap4} + 1, 0.978 ; 178Hz\nwrap ${mem.ap4}, -0.978\nrda ${mem.ap5} + 1, 0.84 ; 1289Hz\nwrap ${mem.ap5}, -0.84\nrda ${mem.ap6} + 1, 0.0\nwrap ${mem.ap6}, 0.0\nwrax ${reg.sigc}, 0.0\n\n; 5. Update Oscillator (Quadrature oscillator)\nrdax ${reg.cososc}, 1.0\nmulx ${reg.shift_amount}\nrdax ${reg.sinosc}, 1.0\nwrax ${reg.sinosc}, -1.0\nmulx ${reg.shift_amount}\nrdax ${reg.cososc}, 1.0\nwrax ${reg.cososc}, 0.0\n\n; 6. Modulation and Summing (Hilbert - SpinCAD pattern)\n; Sum = -2 * (in_c * cos + in_s * sin) -> Frequency DOWN if rate > 0\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc}\nwrax ${reg.temp}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc}\nrdax ${reg.temp}, 1.0\n\n; Scale back up to recovery signal level\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${output.out}, 0.0",
|
|
1972
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.pitch.pitch_offset\",\n \"name\": \"Pitch Offset (Hilbert)\",\n \"category\": \"Effects\",\n \"subcategory\": \"Pitch\",\n \"description\": \"Bipolar frequency shift (+/-). Neutral at 12 o'clock, turning down lowers pitch, turning up raises pitch.\",\n \"color\": \"#fcba03\",\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"shift_ctrl\",\n \"name\": \"Shift CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"shiftValue\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"shiftRange\",\n \"name\": \"Shift Range (Hz)\",\n \"type\": \"number\",\n \"default\": 600,\n \"min\": 1,\n \"max\": 2000,\n \"conversion\": \"HZ_TO_HILBERT_SHIFT\",\n \"description\": \"The total frequency range covered by the Shift control (e.g. 600 means +/- 300Hz).\"\n },\n {\n \"id\": \"shiftValue\",\n \"name\": \"Shift\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Manual control for pitch shift. 0.5 is neutral (no shift).\"\n }\n ],\n \"registers\": [\n \"sigs\",\n \"sigc\",\n \"lpf\",\n \"hpf\",\n \"sigfil\",\n \"sinosc\",\n \"cososc\",\n \"temp\",\n \"shift_amount\",\n \"potfil\"\n ],\n \"memories\": [\n { \"id\": \"ap1\", \"size\": 2 },\n { \"id\": \"ap2\", \"size\": 2 },\n { \"id\": \"ap3\", \"size\": 2 },\n { \"id\": \"ap4\", \"size\": 2 },\n { \"id\": \"ap5\", \"size\": 2 },\n { \"id\": \"ap6\", \"size\": 2 }\n ]\n}\n---\n@section header\n\n@section init\n; Initialize oscillator (cosine = 1.0)\nskp run, done_init\nor $7fffff\nwrax ${reg.cososc}, 0.0\ndone_init:\n\n@section main\n; 1. Process CV and smoothing\n@cv shift_ctrl\n; ACC = Shift position (0..1, defaults to 0.5)\nrdfx ${reg.potfil}, 0.001\nwrlx ${reg.potfil}, -1.0\n; Map [0..1] to [Range/2 .. -Range/2]\n; Bipolar: (0.5 - shiftValue) * Range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0 ; Substitutes converted HZ_TO_HILBERT_SHIFT value\nwrax ${reg.shift_amount}, 0.0\n\n; 2. Audio input filtering (300Hz HPF, 3kHz LPF)\nrdax ${input.in}, 1.0\nrdfx ${reg.hpf}, 0.04\nwrhx ${reg.hpf}, -1.0\nrdfx ${reg.lpf}, 0.4\nwrlx ${reg.lpf}, -1.0\nwrax ${reg.sigfil}, 0.0039 ; Attenuate to avoid clipping in Hilbert chain\n\n; 3. All-pass phase shifter bank (Sine path)\nrda ${mem.ap1} + 1, 0.995 ; 44Hz\nwrap ${mem.ap1}, -0.995\nrda ${mem.ap2} + 1, 0.937 ; 488Hz\nwrap ${mem.ap2}, -0.937\nrda ${mem.ap3} + 1, 0.61 ; 3531Hz\nwrap ${mem.ap3}, -0.61\nwrax ${reg.sigs}, 0.0\n\n; 4. All-pass phase shifter bank (Cosine path)\nrdax ${reg.sigfil}, 0.0039 ; Match Sine path attenuation\nrda ${mem.ap4} + 1, 0.978 ; 178Hz\nwrap ${mem.ap4}, -0.978\nrda ${mem.ap5} + 1, 0.84 ; 1289Hz\nwrap ${mem.ap5}, -0.84\nrda ${mem.ap6} + 1, 0.0\nwrap ${mem.ap6}, 0.0\nwrax ${reg.sigc}, 0.0\n\n; 5. Update Oscillator (Quadrature oscillator)\nrdax ${reg.cososc}, 1.0\nmulx ${reg.shift_amount}\nrdax ${reg.sinosc}, 1.0\nwrax ${reg.sinosc}, -1.0\nmulx ${reg.shift_amount}\nrdax ${reg.cososc}, 1.0\nwrax ${reg.cososc}, 0.0\n\n; 6. Modulation and Summing (Hilbert - SpinCAD pattern)\n; Sum = -2 * (in_c * cos + in_s * sin) -> Frequency DOWN if rate > 0\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc}\nwrax ${reg.temp}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc}\nrdax ${reg.temp}, 1.0\n\n; Scale back up to recovery signal level\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${output.out}, 0.0\n"
|
|
1973
1973
|
},
|
|
1974
1974
|
{
|
|
1975
1975
|
"type": "effects.pitch.pitch_offset_dual",
|
|
@@ -2082,8 +2082,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2082
2082
|
"size": 2
|
|
2083
2083
|
}
|
|
2084
2084
|
],
|
|
2085
|
-
"template": "@section header\
|
|
2086
|
-
"_rawAtl": "---\
|
|
2085
|
+
"template": "@section header\n\n@section init\n; Initialize oscillators (cosine = 1.0)\nskp run, done_init\nor $7fffff\nwrax ${reg.cososc1}, 1.0\nwrax ${reg.cososc2}, 0.0\ndone_init:\n\n@section main\n; 1. Process CVs and smoothing\n@cv shift1_ctrl\nrdfx ${reg.potfil1}, 0.001\nwrlx ${reg.potfil1}, -1.0\n; Bipolar mapping: ACC = (0.5 - shift1) * range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0\nwrax ${reg.shift1_amt}, 0.0\n\n@cv shift2_ctrl\nrdfx ${reg.potfil2}, 0.001\nwrlx ${reg.potfil2}, -1.0\n; Bipolar mapping: ACC = (0.5 - shift2) * range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0\nwrax ${reg.shift2_amt}, 0.0\n\n; 2. Audio input filtering\nrdax ${input.in}, 1.0\nrdfx ${reg.hpf}, 0.04\nwrhx ${reg.hpf}, -1.0\nrdfx ${reg.lpf}, 0.4\nwrlx ${reg.lpf}, -1.0\nwrax ${reg.sigfil}, 0.0039\n\n; 3. Hilbert phase shifter (Shared)\n; Sine path\nrda ${mem.ap1} + 1, 0.995 ; 44Hz\nwrap ${mem.ap1}, -0.995\nrda ${mem.ap2} + 1, 0.937 ; 488Hz\nwrap ${mem.ap2}, -0.937\nrda ${mem.ap3} + 1, 0.61 ; 3531Hz\nwrap ${mem.ap3}, -0.61\nwrax ${reg.sigs}, 0.0\n\n; Cosine path\nrdax ${reg.sigfil}, 0.0039\nrda ${mem.ap4} + 1, 0.978 ; 178Hz\nwrap ${mem.ap4}, -0.978\nrda ${mem.ap5} + 1, 0.84 ; 1289Hz\nwrap ${mem.ap5}, -0.84\nrda ${mem.ap6} + 1, 0.0\nwrap ${mem.ap6}, 0.0\nwrax ${reg.sigc}, 0.0\n\n; 4. Oscillator 1 update\nrdax ${reg.cososc1}, 1.0\nmulx ${reg.shift1_amt}\nrdax ${reg.sinosc1}, 1.0\nwrax ${reg.sinosc1}, -1.0\nmulx ${reg.shift1_amt}\nrdax ${reg.cososc1}, 1.0\nwrax ${reg.cososc1}, 0.0\n\n; 5. Pitch shift 1 calculation\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc1}\nwrax ${reg.temp1}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc1}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.temp1}, 0.0\n\n; 6. Oscillator 2 update\nrdax ${reg.cososc2}, 1.0\nmulx ${reg.shift2_amt}\nrdax ${reg.sinosc2}, 1.0\nwrax ${reg.sinosc2}, -1.0\nmulx ${reg.shift2_amt}\nrdax ${reg.cososc2}, 1.0\nwrax ${reg.cososc2}, 0.0\n\n; 7. Pitch shift 2 calculation\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc2}\nwrax ${reg.temp2}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc2}\nrdax ${reg.temp2}, 1.0\n\n; 8. Sum results and scale up\nrdax ${reg.temp1}, 0.5 ; Mix\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${output.out}, 0.0",
|
|
2086
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.pitch.pitch_offset_dual\",\n \"name\": \"Dual Pitch Offset (Hilbert)\",\n \"category\": \"Effects\",\n \"subcategory\": \"Pitch\",\n \"description\": \"Two independent bipolar frequency offsets mixed to a mono output.\",\n \"color\": \"#fcba03\",\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"shift1_ctrl\",\n \"name\": \"Shift 1 CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"shiftValue1\"\n },\n {\n \"id\": \"shift2_ctrl\",\n \"name\": \"Shift 2 CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"shiftValue2\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"shiftRange\",\n \"name\": \"Shift Range (Hz)\",\n \"type\": \"number\",\n \"default\": 600,\n \"min\": 1,\n \"max\": 2000,\n \"conversion\": \"HZ_TO_HILBERT_SHIFT\",\n \"description\": \"Total frequency range for both controls.\"\n },\n {\n \"id\": \"shiftValue1\",\n \"name\": \"Shift 1\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Bipolar control for shift 1.\"\n },\n {\n \"id\": \"shiftValue2\",\n \"name\": \"Shift 2\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Bipolar control for shift 2.\"\n }\n ],\n \"registers\": [\n \"sigs\",\n \"sigc\",\n \"lpf\",\n \"hpf\",\n \"sigfil\",\n \"sinosc1\",\n \"cososc1\",\n \"sinosc2\",\n \"cososc2\",\n \"temp1\",\n \"temp2\",\n \"shift1_amt\",\n \"shift2_amt\",\n \"potfil1\",\n \"potfil2\"\n ],\n \"memories\": [\n { \"id\": \"ap1\", \"size\": 2 },\n { \"id\": \"ap2\", \"size\": 2 },\n { \"id\": \"ap3\", \"size\": 2 },\n { \"id\": \"ap4\", \"size\": 2 },\n { \"id\": \"ap5\", \"size\": 2 },\n { \"id\": \"ap6\", \"size\": 2 }\n ]\n}\n---\n@section header\n\n@section init\n; Initialize oscillators (cosine = 1.0)\nskp run, done_init\nor $7fffff\nwrax ${reg.cososc1}, 1.0\nwrax ${reg.cososc2}, 0.0\ndone_init:\n\n@section main\n; 1. Process CVs and smoothing\n@cv shift1_ctrl\nrdfx ${reg.potfil1}, 0.001\nwrlx ${reg.potfil1}, -1.0\n; Bipolar mapping: ACC = (0.5 - shift1) * range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0\nwrax ${reg.shift1_amt}, 0.0\n\n@cv shift2_ctrl\nrdfx ${reg.potfil2}, 0.001\nwrlx ${reg.potfil2}, -1.0\n; Bipolar mapping: ACC = (0.5 - shift2) * range\nsof -1.0, 0.5\nsof ${shiftRange}, 0.0\nwrax ${reg.shift2_amt}, 0.0\n\n; 2. Audio input filtering\nrdax ${input.in}, 1.0\nrdfx ${reg.hpf}, 0.04\nwrhx ${reg.hpf}, -1.0\nrdfx ${reg.lpf}, 0.4\nwrlx ${reg.lpf}, -1.0\nwrax ${reg.sigfil}, 0.0039\n\n; 3. Hilbert phase shifter (Shared)\n; Sine path\nrda ${mem.ap1} + 1, 0.995 ; 44Hz\nwrap ${mem.ap1}, -0.995\nrda ${mem.ap2} + 1, 0.937 ; 488Hz\nwrap ${mem.ap2}, -0.937\nrda ${mem.ap3} + 1, 0.61 ; 3531Hz\nwrap ${mem.ap3}, -0.61\nwrax ${reg.sigs}, 0.0\n\n; Cosine path\nrdax ${reg.sigfil}, 0.0039\nrda ${mem.ap4} + 1, 0.978 ; 178Hz\nwrap ${mem.ap4}, -0.978\nrda ${mem.ap5} + 1, 0.84 ; 1289Hz\nwrap ${mem.ap5}, -0.84\nrda ${mem.ap6} + 1, 0.0\nwrap ${mem.ap6}, 0.0\nwrax ${reg.sigc}, 0.0\n\n; 4. Oscillator 1 update\nrdax ${reg.cososc1}, 1.0\nmulx ${reg.shift1_amt}\nrdax ${reg.sinosc1}, 1.0\nwrax ${reg.sinosc1}, -1.0\nmulx ${reg.shift1_amt}\nrdax ${reg.cososc1}, 1.0\nwrax ${reg.cososc1}, 0.0\n\n; 5. Pitch shift 1 calculation\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc1}\nwrax ${reg.temp1}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc1}\nrdax ${reg.temp1}, 1.0\nwrax ${reg.temp1}, 0.0\n\n; 6. Oscillator 2 update\nrdax ${reg.cososc2}, 1.0\nmulx ${reg.shift2_amt}\nrdax ${reg.sinosc2}, 1.0\nwrax ${reg.sinosc2}, -1.0\nmulx ${reg.shift2_amt}\nrdax ${reg.cososc2}, 1.0\nwrax ${reg.cososc2}, 0.0\n\n; 7. Pitch shift 2 calculation\nrdax ${reg.sigc}, -2.0\nmulx ${reg.cososc2}\nwrax ${reg.temp2}, 0.0\nrdax ${reg.sigs}, -2.0\nmulx ${reg.sinosc2}\nrdax ${reg.temp2}, 1.0\n\n; 8. Sum results and scale up\nrdax ${reg.temp1}, 0.5 ; Mix\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nsof -2.0, 0.0\nwrax ${output.out}, 0.0\n"
|
|
2087
2087
|
},
|
|
2088
2088
|
{
|
|
2089
2089
|
"type": "effects.pitch.pitch_shift",
|
|
@@ -2180,8 +2180,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2180
2180
|
}
|
|
2181
2181
|
],
|
|
2182
2182
|
"registers": [],
|
|
2183
|
-
"template": "@section header\
|
|
2184
|
-
"_rawAtl": "---\
|
|
2183
|
+
"template": "@section header\n@if lfoSel == 0\n@equals lfo RMP0\n@equals lfo_rate RMP0_RATE\n@else\n@equals lfo RMP1\n@equals lfo_rate RMP1_RATE\n@endif\n\n@section init\n; Initialize Ramp LFO\nskp run, done_init\nwldr ${lfoSel}, ${semitones}, ${lfoWidth}\ndone_init:\n\n@section main\n; Write input to delay buffer\nrdax ${input.in}, 1.0\nwra ${mem.buffer}, 0.0\n\n; Update pitch shift rate via CV\n@cv pitch_ctrl\nwrax ${lfo_rate}, 0.0\n\n; Perform pitch shift (dual-tap for crossfading)\ncho rda, ${lfo}, REG | COMPC, ${mem.buffer}\ncho rda, ${lfo}, 0, ${mem.buffer} + 1\nwra ${mem.temp}, 0.0\n\ncho rda, ${lfo}, RPTR2 | COMPC, ${mem.buffer}\ncho rda, ${lfo}, RPTR2, ${mem.buffer} + 1\ncho sof, ${lfo}, NA | COMPC, 0.0\ncho rda, ${lfo}, NA, ${mem.temp}\n\nwrax ${output.out}, 0.0",
|
|
2184
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.pitch.pitch_shift\",\n \"name\": \"Pitch Shift\",\n \"category\": \"Effects\",\n \"subcategory\": \"Pitch\",\n \"description\": \"Adjustable pitch shifter using Ramp LFOs.\",\n \"color\": \"#fcba03\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"pitch_ctrl\",\n \"name\": \"Pitch CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"semitones\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"semitones\",\n \"name\": \"Pitch (Semitones)\",\n \"type\": \"number\",\n \"default\": 12,\n \"min\": -24,\n \"max\": 24,\n \"step\": 0.1,\n \"conversion\": \"SEMITONES_TO_RATE\",\n \"description\": \"Base pitch shift in semitones. If Pitch CV is connected, this acts as the maximum shift range.\"\n },\n {\n \"id\": \"lfoWidth\",\n \"name\": \"Buffer Size\",\n \"type\": \"select\",\n \"default\": 4096,\n \"options\": [\n { \"label\": \"4096 (Smooth)\", \"value\": 4096 },\n { \"label\": \"2048\", \"value\": 2048 },\n { \"label\": \"1024\", \"value\": 1024 },\n { \"label\": \"512 (Lo-fi)\", \"value\": 512 }\n ],\n \"description\": \"Size of the pitch shift buffer. Larger values are smoother but add more latency.\"\n },\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Slot\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n { \"label\": \"Ramp 0\", \"value\": 0 },\n { \"label\": \"Ramp 1\", \"value\": 1 }\n ]\n }\n ],\n \"memories\": [\n {\n \"id\": \"buffer\",\n \"size\": \"lfoWidth\"\n },\n {\n \"id\": \"temp\",\n \"size\": 1\n }\n ],\n \"registers\": []\n}\n---\n@section header\n@if lfoSel == 0\n@equals lfo RMP0\n@equals lfo_rate RMP0_RATE\n@else\n@equals lfo RMP1\n@equals lfo_rate RMP1_RATE\n@endif\n\n@section init\n; Initialize Ramp LFO\nskp run, done_init\nwldr ${lfoSel}, ${semitones}, ${lfoWidth}\ndone_init:\n\n@section main\n; Write input to delay buffer\nrdax ${input.in}, 1.0\nwra ${mem.buffer}, 0.0\n\n; Update pitch shift rate via CV\n@cv pitch_ctrl\nwrax ${lfo_rate}, 0.0\n\n; Perform pitch shift (dual-tap for crossfading)\ncho rda, ${lfo}, REG | COMPC, ${mem.buffer}\ncho rda, ${lfo}, 0, ${mem.buffer} + 1\nwra ${mem.temp}, 0.0\n\ncho rda, ${lfo}, RPTR2 | COMPC, ${mem.buffer}\ncho rda, ${lfo}, RPTR2, ${mem.buffer} + 1\ncho sof, ${lfo}, NA | COMPC, 0.0\ncho rda, ${lfo}, NA, ${mem.temp}\n\nwrax ${output.out}, 0.0\n"
|
|
2185
2185
|
},
|
|
2186
2186
|
{
|
|
2187
2187
|
"type": "effects.platereverb",
|
|
@@ -2343,8 +2343,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2343
2343
|
"temp",
|
|
2344
2344
|
"temp2"
|
|
2345
2345
|
],
|
|
2346
|
-
"template": "@section header\
|
|
2347
|
-
"_rawAtl": "---\
|
|
2346
|
+
"template": "@section header\n@equals decayLimit 0.8\n@equals c0_35 0.35\n@equals c0_10 0.10\n@equals c0_25 0.25\n@equals c0_99 0.99\n@equals c0_999 0.9990234375\n@equals inputDiff1 0.75\n@equals inputDiff2 0.625\n@equals decayDiff1 0.70\n@equals bandwidth 0.31852 ; 1 - 0.68148\n@equals tap0_6 0.6\n@equals tapNeg0_6 -0.6\n@equals 8 8\n\n@section init\n; Plate Reverb init\nskp run, done\nwlds SIN0, 27, 8\nwlds SIN1, 23, 8\ndone:\n\n@section main\n; Calculate decay time\n@cv decayTimeCV\nsof ${decayLimit}, 0.0\nwrax ${reg.decay}, 1.0\n\n; Calculate decay_diffusion_2\nsof 1.0, -${c0_35}\nskp neg, 1\nclr\nsof 1.0, ${c0_35}\nsof 1.0, -${c0_10}\nskp gez, 1\nclr\nsof 1.0, ${c0_25}\nwrax ${reg.decay_diffusion_2}, 0.0\n\n; Damping\n@cv dampingCV\nsof -1.0, ${c0_99}\nwrax ${reg.damping_reg}, -1.0\nsof 1.0, ${c0_999}\nwrax ${reg.one_minus_dmpg}, 0.0\n\n; Mono sum and pre-delay\nrdax ${input.in}, 1.0\nwrax ${reg.mono}, 1.0\nwra ${mem.predelay}, 0.0\n\n; Input low-pass\nrda ${mem.predelay}#, ${bandwidth}\nrdax ${reg.lp_inp}, 1.0-${bandwidth}\nwrax ${reg.lp_inp}, 1.0\n\n; Input diffusion\nrda ${mem.ap13_14}#, -${inputDiff1}\nwrap ${mem.ap13_14}, ${inputDiff1}\n\n@if density != 'Economy'\nrda ${mem.ap15_16}#, -${inputDiff2}\nwrap ${mem.ap15_16}, ${inputDiff2}\n@endif\n\n@if density == 'High'\nrda ${mem.ap19_20}#, -${inputDiff1}\nwrap ${mem.ap19_20}, ${inputDiff1}\nrda ${mem.ap21_22}#, -${inputDiff2}\nwrap ${mem.ap21_22}, ${inputDiff2}\n@endif\n\nwrax ${reg.diffuse_in}, 0.0\n\n; Left Tank\nrda ${mem.del59_63}#, 1.0\nmulx ${reg.decay}\nrdax ${reg.diffuse_in}, 1.0\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN0, SIN|REG|COMPC, ${mem.ap23_24}#-8-1\ncho rda, SIN0, SIN, ${mem.ap23_24}#-8\nwrax ${reg.temp2}, ${decayDiff1}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap23_24}, -${decayDiff1}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del24_30}, 0.0\nrda ${mem.del24_30}#, 1.0\n\n; Tank LP\nmulx ${reg.one_minus_dmpg}\nwrax ${reg.temp}, 0.0\nrdax ${reg.lp30_31}, 1.0\nmulx ${reg.damping_reg}\nrdax ${reg.temp}, 1.0\nwrax ${reg.lp30_31}, 1.0\nmulx ${reg.decay}\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN1, COS|REG|COMPC, ${mem.ap31_33}#-8-1\ncho rda, SIN1, COS, ${mem.ap31_33}#-8\nwrax ${reg.temp2}, -1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap31_33}, 1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del33_39}, 0.0\nrda ${mem.del33_39}#, 1.0\n\n; Right Tank\nmulx ${reg.decay}\nrdax ${reg.diffuse_in}, 1.0\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN0, COS|REG|COMPC, ${mem.ap46_48}#-8-1\ncho rda, SIN0, COS, ${mem.ap46_48}#-8\nwrax ${reg.temp2}, ${decayDiff1}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap46_48}, -${decayDiff1}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del48_54}, 0.0\nrda ${mem.del48_54}#, 1.0\n\nmulx ${reg.one_minus_dmpg}\nwrax ${reg.temp}, 0.0\nrdax ${reg.lp54_55}, 1.0\nmulx ${reg.damping_reg}\nrdax ${reg.temp}, 1.0\nwrax ${reg.lp54_55}, 1.0\nmulx ${reg.decay}\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN1, SIN|REG|COMPC, ${mem.ap55_59}#-8-1\ncho rda, SIN1, SIN, ${mem.ap55_59}#-8\nwrax ${reg.temp2}, -1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap55_59}, 1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del59_63}, 0.0\n\n; Left Output Taps\nrda ${mem.del48_54}+292, ${tap0_6}\nrda ${mem.del24_30}+2192, ${tapNeg0_6}\n\n@if density != 'Economy'\nrda ${mem.del48_54}+3274, ${tap0_6}\nrda ${mem.del33_39}+1174, ${tapNeg0_6}\n@endif\n\n@if density == 'High'\nrda ${mem.ap55_59}+2107, ${tapNeg0_6}\nrda ${mem.del59_63}+2198, ${tap0_6}\nrda ${mem.ap31_33}+205, ${tapNeg0_6}\n@endif\n\nwrax ${output.outL}, 0.0\n\n; Right Output Taps\nrda ${mem.del24_30}+389, ${tap0_6}\nrda ${mem.del59_63}+133, ${tapNeg0_6}\n\n@if density != 'Economy'\nrda ${mem.del24_30}+3993, ${tap0_6}\nrda ${mem.del48_54}+2325, ${tapNeg0_6}\n@endif\n\n@if density == 'High'\nrda ${mem.ap31_33}+1352, ${tapNeg0_6}\nrda ${mem.del33_39}+2943, ${tap0_6}\nrda ${mem.ap55_59}+369, ${tapNeg0_6}\n@endif\n\nwrax ${output.outR}, 0.0",
|
|
2347
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.platereverb\",\n \"name\": \"Plate Reverb\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"description\": \"High-quality plate reverb\",\n \"color\": \"#7100FC\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"dampingCV\",\n \"name\": \"Damping\",\n \"type\": \"control\",\n \"parameter\": \"damping\"\n },\n {\n \"id\": \"decayTimeCV\",\n \"name\": \"Decay Time\",\n \"type\": \"control\",\n \"parameter\": \"decayTime\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"outL\",\n \"name\": \"Left\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"outR\",\n \"name\": \"Right\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"damping\",\n \"name\": \"Damping\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"description\": \"High-frequency damping in the reverb tanks (0.0 to 1.0 feedback coefficient).\",\n \"step\": 0.01\n },\n {\n \"id\": \"decayTime\",\n \"name\": \"Decay Time\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"description\": \"Reverb decay length (T60/feedback coefficient 0.0 to 1.0).\",\n \"step\": 0.01\n },\n {\n \"id\": \"preDelay\",\n \"name\": \"Pre-Delay (ms)\",\n \"type\": \"number\",\n \"default\": 20,\n \"min\": 0,\n \"max\": 100,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"Initial delay before reverb onset in ms. This is the only parameter that affects memory allocation.\",\n \"step\": 0.1\n },\n {\n \"id\": \"density\",\n \"name\": \"Density\",\n \"type\": \"select\",\n \"default\": \"High\",\n \"options\": [\n {\n \"value\": \"High\",\n \"label\": \"High (4-stage diffusion, 14 taps)\"\n },\n {\n \"value\": \"Standard\",\n \"label\": \"Standard (2-stage diffusion, 8 taps)\"\n },\n {\n \"value\": \"Economy\",\n \"label\": \"Economy (1-stage diffusion, 4 taps)\"\n }\n ],\n \"description\": \"Adjusts complexity to save instructions. Economy uses ~70, High uses ~110.\"\n }\n ],\n \"memories\": [\n {\n \"id\": \"predelay\",\n \"size\": \"preDelay\"\n },\n {\n \"id\": \"ap13_14\",\n \"size\": 156\n },\n {\n \"id\": \"ap19_20\",\n \"size\": 117\n },\n {\n \"id\": \"ap15_16\",\n \"size\": 417\n },\n {\n \"id\": \"ap21_22\",\n \"size\": 305\n },\n {\n \"id\": \"ap23_24\",\n \"size\": 748\n },\n {\n \"id\": \"del24_30\",\n \"size\": 4903\n },\n {\n \"id\": \"ap31_33\",\n \"size\": 1990\n },\n {\n \"id\": \"del33_39\",\n \"size\": 4096\n },\n {\n \"id\": \"ap46_48\",\n \"size\": 1008\n },\n {\n \"id\": \"del48_54\",\n \"size\": 4643\n },\n {\n \"id\": \"ap55_59\",\n \"size\": 2932\n },\n {\n \"id\": \"del59_63\",\n \"size\": 3483\n }\n ],\n \"registers\": [\n \"decay\",\n \"decay_diffusion_2\",\n \"damping_reg\",\n \"one_minus_dmpg\",\n \"lp_inp\",\n \"lp30_31\",\n \"lp54_55\",\n \"mono\",\n \"diffuse_in\",\n \"temp\",\n \"temp2\"\n ]\n}\n---\n@section header\n@equals decayLimit 0.8\n@equals c0_35 0.35\n@equals c0_10 0.10\n@equals c0_25 0.25\n@equals c0_99 0.99\n@equals c0_999 0.9990234375\n@equals inputDiff1 0.75\n@equals inputDiff2 0.625\n@equals decayDiff1 0.70\n@equals bandwidth 0.31852 ; 1 - 0.68148\n@equals tap0_6 0.6\n@equals tapNeg0_6 -0.6\n@equals 8 8\n\n@section init\n; Plate Reverb init\nskp run, done\nwlds SIN0, 27, 8\nwlds SIN1, 23, 8\ndone:\n\n@section main\n; Calculate decay time\n@cv decayTimeCV\nsof ${decayLimit}, 0.0\nwrax ${reg.decay}, 1.0\n\n; Calculate decay_diffusion_2\nsof 1.0, -${c0_35}\nskp neg, 1\nclr\nsof 1.0, ${c0_35}\nsof 1.0, -${c0_10}\nskp gez, 1\nclr\nsof 1.0, ${c0_25}\nwrax ${reg.decay_diffusion_2}, 0.0\n\n; Damping\n@cv dampingCV\nsof -1.0, ${c0_99}\nwrax ${reg.damping_reg}, -1.0\nsof 1.0, ${c0_999}\nwrax ${reg.one_minus_dmpg}, 0.0\n\n; Mono sum and pre-delay\nrdax ${input.in}, 1.0\nwrax ${reg.mono}, 1.0\nwra ${mem.predelay}, 0.0\n\n; Input low-pass\nrda ${mem.predelay}#, ${bandwidth}\nrdax ${reg.lp_inp}, 1.0-${bandwidth}\nwrax ${reg.lp_inp}, 1.0\n\n; Input diffusion\nrda ${mem.ap13_14}#, -${inputDiff1}\nwrap ${mem.ap13_14}, ${inputDiff1}\n\n@if density != 'Economy'\nrda ${mem.ap15_16}#, -${inputDiff2}\nwrap ${mem.ap15_16}, ${inputDiff2}\n@endif\n\n@if density == 'High'\nrda ${mem.ap19_20}#, -${inputDiff1}\nwrap ${mem.ap19_20}, ${inputDiff1}\nrda ${mem.ap21_22}#, -${inputDiff2}\nwrap ${mem.ap21_22}, ${inputDiff2}\n@endif\n\nwrax ${reg.diffuse_in}, 0.0\n\n; Left Tank\nrda ${mem.del59_63}#, 1.0\nmulx ${reg.decay}\nrdax ${reg.diffuse_in}, 1.0\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN0, SIN|REG|COMPC, ${mem.ap23_24}#-8-1\ncho rda, SIN0, SIN, ${mem.ap23_24}#-8\nwrax ${reg.temp2}, ${decayDiff1}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap23_24}, -${decayDiff1}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del24_30}, 0.0\nrda ${mem.del24_30}#, 1.0\n\n; Tank LP\nmulx ${reg.one_minus_dmpg}\nwrax ${reg.temp}, 0.0\nrdax ${reg.lp30_31}, 1.0\nmulx ${reg.damping_reg}\nrdax ${reg.temp}, 1.0\nwrax ${reg.lp30_31}, 1.0\nmulx ${reg.decay}\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN1, COS|REG|COMPC, ${mem.ap31_33}#-8-1\ncho rda, SIN1, COS, ${mem.ap31_33}#-8\nwrax ${reg.temp2}, -1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap31_33}, 1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del33_39}, 0.0\nrda ${mem.del33_39}#, 1.0\n\n; Right Tank\nmulx ${reg.decay}\nrdax ${reg.diffuse_in}, 1.0\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN0, COS|REG|COMPC, ${mem.ap46_48}#-8-1\ncho rda, SIN0, COS, ${mem.ap46_48}#-8\nwrax ${reg.temp2}, ${decayDiff1}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap46_48}, -${decayDiff1}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del48_54}, 0.0\nrda ${mem.del48_54}#, 1.0\n\nmulx ${reg.one_minus_dmpg}\nwrax ${reg.temp}, 0.0\nrdax ${reg.lp54_55}, 1.0\nmulx ${reg.damping_reg}\nrdax ${reg.temp}, 1.0\nwrax ${reg.lp54_55}, 1.0\nmulx ${reg.decay}\nwrax ${reg.temp}, 0.0\n\ncho rda, SIN1, SIN|REG|COMPC, ${mem.ap55_59}#-8-1\ncho rda, SIN1, SIN, ${mem.ap55_59}#-8\nwrax ${reg.temp2}, -1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp}, 1.0\nwra ${mem.ap55_59}, 1.0\nmulx ${reg.decay_diffusion_2}\nrdax ${reg.temp2}, 1.0\n\nwra ${mem.del59_63}, 0.0\n\n; Left Output Taps\nrda ${mem.del48_54}+292, ${tap0_6}\nrda ${mem.del24_30}+2192, ${tapNeg0_6}\n\n@if density != 'Economy'\nrda ${mem.del48_54}+3274, ${tap0_6}\nrda ${mem.del33_39}+1174, ${tapNeg0_6}\n@endif\n\n@if density == 'High'\nrda ${mem.ap55_59}+2107, ${tapNeg0_6}\nrda ${mem.del59_63}+2198, ${tap0_6}\nrda ${mem.ap31_33}+205, ${tapNeg0_6}\n@endif\n\nwrax ${output.outL}, 0.0\n\n; Right Output Taps\nrda ${mem.del24_30}+389, ${tap0_6}\nrda ${mem.del59_63}+133, ${tapNeg0_6}\n\n@if density != 'Economy'\nrda ${mem.del24_30}+3993, ${tap0_6}\nrda ${mem.del48_54}+2325, ${tapNeg0_6}\n@endif\n\n@if density == 'High'\nrda ${mem.ap31_33}+1352, ${tapNeg0_6}\nrda ${mem.del33_39}+2943, ${tap0_6}\nrda ${mem.ap55_59}+369, ${tapNeg0_6}\n@endif\n\nwrax ${output.outR}, 0.0\n\n"
|
|
2348
2348
|
},
|
|
2349
2349
|
{
|
|
2350
2350
|
"type": "effects.reverb.min",
|
|
@@ -2426,8 +2426,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2426
2426
|
"apout",
|
|
2427
2427
|
"dry"
|
|
2428
2428
|
],
|
|
2429
|
-
"template": "; Minimal 100% wet reverb\
|
|
2430
|
-
"_rawAtl": "---\
|
|
2429
|
+
"template": "; Minimal 100% wet reverb\n@equals kap 0.325\n\n; Store dry signal\nrdax ${input.input}, 1.0\nwrax ${reg.dry}, 0.0\n\n; Input with scaling to prevent clipping (wet path)\nrdax ${reg.dry}, 0.25\n\n; 4 series input allpass filters\nrda ${mem.api1}#, ${kap}\nwrap ${mem.api1}, -1.0\nrda ${mem.api2}#, ${kap}\nwrap ${mem.api2}, -1.0\nrda ${mem.api3}#, ${kap}\nwrap ${mem.api3}, -1.0\nrda ${mem.api4}#, ${kap}\nwrap ${mem.api4}, -1.0\n\n; Save allpass output for second loop\nwrax ${reg.apout}, 1.0\n\n; First loop delay\nrda ${mem.del2}#, 1.0\n@mulcv reverb_time\n\n; Loop allpass 1\nrda ${mem.ap1}#, -${kap}\nwrap ${mem.ap1}, ${kap}\n\n; Write to delay 1\nwra ${mem.del1}, 1.99\n\n; Second loop delay\nrdax ${reg.apout}, 1.0\n\nrda ${mem.del1}#, 1.0\n@mulcv reverb_time\n\n; Loop allpass 2\nrda ${mem.ap2}#, -${kap}\nwrap ${mem.ap2}, ${kap}\n\n; Write to delay 2 and output\nwra ${mem.del2}, 1.99\n\n; Export final wet signal (already at 0.25 scale)\nwrax ${output.output}, 0.0",
|
|
2430
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.reverb.min\",\n \"name\": \"Simple Reverb\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"description\": \"Minimal 100% wet reverb with 4 input allpass and 2 delay loops. Reverb time can be controlled via parameter or external CV.\",\n \"color\": \"#7100FC\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"reverb_time\",\n \"name\": \"Reverb Time\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"reverbTime\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Audio Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"reverbTime\",\n \"name\": \"Reverb Time\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 0.99,\n \"description\": \"Feedback coefficient for the reverb tail (0.0 to 0.99). Controls the decay length.\",\n \"step\": 0.01\n }\n ],\n \"memories\": [\n {\n \"id\": \"api1\",\n \"size\": 122\n },\n {\n \"id\": \"api2\",\n \"size\": 303\n },\n {\n \"id\": \"api3\",\n \"size\": 553\n },\n {\n \"id\": \"api4\",\n \"size\": 922\n },\n {\n \"id\": \"ap1\",\n \"size\": 3823\n },\n {\n \"id\": \"del1\",\n \"size\": 6512\n },\n {\n \"id\": \"ap2\",\n \"size\": 4732\n },\n {\n \"id\": \"del2\",\n \"size\": 5016\n }\n ],\n \"registers\": [\n \"apout\",\n \"dry\"\n ]\n}\n---\n; Minimal 100% wet reverb\n@equals kap 0.325\n\n; Store dry signal\nrdax ${input.input}, 1.0\nwrax ${reg.dry}, 0.0\n\n; Input with scaling to prevent clipping (wet path)\nrdax ${reg.dry}, 0.25\n\n; 4 series input allpass filters\nrda ${mem.api1}#, ${kap}\nwrap ${mem.api1}, -1.0\nrda ${mem.api2}#, ${kap}\nwrap ${mem.api2}, -1.0\nrda ${mem.api3}#, ${kap}\nwrap ${mem.api3}, -1.0\nrda ${mem.api4}#, ${kap}\nwrap ${mem.api4}, -1.0\n\n; Save allpass output for second loop\nwrax ${reg.apout}, 1.0\n\n; First loop delay\nrda ${mem.del2}#, 1.0\n@mulcv reverb_time\n\n; Loop allpass 1\nrda ${mem.ap1}#, -${kap}\nwrap ${mem.ap1}, ${kap}\n\n; Write to delay 1\nwra ${mem.del1}, 1.99\n\n; Second loop delay\nrdax ${reg.apout}, 1.0\n\nrda ${mem.del1}#, 1.0\n@mulcv reverb_time\n\n; Loop allpass 2\nrda ${mem.ap2}#, -${kap}\nwrap ${mem.ap2}, ${kap}\n\n; Write to delay 2 and output\nwra ${mem.del2}, 1.99\n\n; Export final wet signal (already at 0.25 scale)\nwrax ${output.output}, 0.0\n"
|
|
2431
2431
|
},
|
|
2432
2432
|
{
|
|
2433
2433
|
"type": "effects.reverb.room",
|
|
@@ -2650,8 +2650,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2650
2650
|
"hp2",
|
|
2651
2651
|
"tlp"
|
|
2652
2652
|
],
|
|
2653
|
-
"template": "@section init\
|
|
2654
|
-
"_rawAtl": "---\
|
|
2653
|
+
"template": "@section init\n@if pinConnected(input)\n; Room Reverb init\nskp run, room_reverb_init\nwrax ${reg.lp1}, 0.0\nwrax ${reg.lp2}, 0.0\nwrax ${reg.hp1}, 0.0\nwrax ${reg.hp2}, 0.0\nwrax ${reg.tlp}, 0.0\nwlds SIN0, ${lfoRate}, 100\nroom_reverb_init:\n@endif\n\n@section main\n@if pinConnected(input)\n\n; Room Reverb\n\n; Evaluate Control Voltages globally\n@cv hf_loss\nwrax ${reg.kd}, 0.0\n\n@cv reverb_time\nwrax ${reg.rt_cv}, 0.0\n\n@cv pre_delay\nsof 0.1, 0.0\nwrax ADDR_PTR, 0.0\n\n; Feed input to pre-delay\nrdax ${input.input}, ${inputGain}\nwra ${mem.pdel}, 0.0\n\n; Read pre-delay and write to tap delay\nrmpa 1.0\nwra ${mem.tdel}, 1.0\n\n; 4 input allpass filters\nrda ${mem.ap1}^, ${inputAllpassCoeff}\nwrap ${mem.ap1}, -${inputAllpassCoeff}\nrda ${mem.ap2}^, ${inputAllpassCoeff}\nwrap ${mem.ap2}, -${inputAllpassCoeff}\nrda ${mem.ap3}^, ${inputAllpassCoeff}\nwrap ${mem.ap3}, -${inputAllpassCoeff}\nrda ${mem.ap4}^, ${inputAllpassCoeff}\nwrap ${mem.ap4}, -${inputAllpassCoeff}\nwrax ${reg.apout}, 0.0\n\n; Delay loop 1\nrda ${mem.d4}^, ${reverbTime}\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap1a}^, ${delayAllpassCoeff}\nwrap ${mem.lap1a}, -${delayAllpassCoeff}\nrda ${mem.lap1b}^, -${delayAllpassCoeff}\nwrap ${mem.lap1b}, ${delayAllpassCoeff}\nrdfx ${reg.hp1}, ${hfDamping}\nwrhx ${reg.hp1}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp1}, 0.5\nwrhx ${reg.lp1}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d1}, 0.0\n\n; Delay loop 2\nrda ${mem.d1}^, -${reverbTime}\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap2a}^, ${delayAllpassCoeff}\nwrap ${mem.lap2a}, -${delayAllpassCoeff}\nrda ${mem.lap2b}^, ${delayAllpassCoeff}\nwrap ${mem.lap2b}, -${delayAllpassCoeff}\nrdfx ${reg.hp2}, ${hfDamping}\nwrhx ${reg.hp2}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp2}, 0.5\nwrhx ${reg.lp2}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d2}, 0.0\n\n; Delay loop 3\nrda ${mem.d2}^, -1.0\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap3a}^, ${delayAllpassCoeff}\nwrap ${mem.lap3a}, -${delayAllpassCoeff}\nrda ${mem.lap3b}^, ${delayAllpassCoeff}\nwrap ${mem.lap3b}, -${delayAllpassCoeff}\nrdfx ${reg.hp2}, 0.05\nwrhx ${reg.hp2}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp3}, 0.5\nwrhx ${reg.lp3}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d3}, 0.0\n\n; Delay loop 4\nrda ${mem.d3}^, -1.0\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap4a}^, ${delayAllpassCoeff}\nwrap ${mem.lap4a}, -${delayAllpassCoeff}\nrda ${mem.lap4b}^, ${delayAllpassCoeff}\nwrap ${mem.lap4b}, -${delayAllpassCoeff}\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp4}, 0.5\nwrhx ${reg.lp4}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d4}, 0.0\n\n; Tap delay processing\nrda ${mem.tdel}+100, 1.0\nrda ${mem.tap1}^, 0.5\nwrap ${mem.tap1}, -0.5\nwrax ${reg.temp}, 1.0\nrdfx ${reg.tlp}, 0.1\nwrhx ${reg.tlp}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.tdel}+101, 0.0\n\nrda ${mem.tdel}+1000, 1.0\nrda ${mem.tap2}^, 0.5\nwrap ${mem.tap2}, -0.5\nwra ${mem.tdel}+1001, 0.0\n\n; Left output mix\nrda ${mem.tdel}+701, 0.7\nrda ${mem.tdel}+956, 0.6\nrda ${mem.tdel}+409, 0.5\nrda ${mem.tdel}+1323, 0.4\n\n@if pinConnected(outputR)\nrda ${mem.d1}, 1.5\n@else\nrda ${mem.d1}^, 0.7\nrda ${mem.d2}^, 0.8\n@endif\n@if pinConnected(outputL)\nwrax ${output.outputL}, 0.0\n@else\nwrax ADDR_PTR, 0.0\n@endif\n\n; Right output mix\n@if pinConnected(outputR)\nrda ${mem.tdel}+582, 0.7\nrda ${mem.tdel}+956, 0.6\nrda ${mem.tdel}+1047, 0.5\nrda ${mem.tdel}+1323, 0.4\nrda ${mem.d3}, 1.5\nwrax ${output.outputR}, 0.0\n@endif\n\n; LFO chorus modulation\ncho rda, SIN0, REG|COMPC, ${mem.lap1b}+100\ncho rda, SIN0, SIN, ${mem.lap1b}+101\nwra ${mem.lap1b}+200, 0.0\n\ncho rda, SIN0, COS|REG|COMPC, ${mem.lap3b}+100\ncho rda, SIN0, COS, ${mem.lap3b}+101\nwra ${mem.lap3b}+200, 0.0\n\n@else\n; Room Reverb (no input connected)\n@endif",
|
|
2654
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.reverb.room\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"name\": \"Room Reverb\",\n \"description\": \"Hall-style reverb with pre-delay, damping, and stereo output\",\n \"color\": \"#7100FC\",\n \"inputs\": [\n { \"id\": \"input\", \"name\": \"Input\", \"type\": \"audio\", \"required\": true },\n { \"id\": \"pre_delay\", \"name\": \"Pre Delay\", \"type\": \"control\", \"required\": false, \"parameter\": \"preDelay\" },\n { \"id\": \"reverb_time\", \"name\": \"Reverb Time\", \"type\": \"control\", \"required\": false, \"parameter\": \"reverbTime\" },\n { \"id\": \"hf_loss\", \"name\": \"HF Loss\", \"type\": \"control\", \"required\": false, \"parameter\": \"hfLoss\" }\n ],\n \"outputs\": [\n { \"id\": \"outputL\", \"name\": \"Output L\", \"type\": \"audio\" },\n { \"id\": \"outputR\", \"name\": \"Output R\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"inputGain\",\n \"name\": \"Input Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"preDelay\",\n \"name\": \"Pre-Delay (ms)\",\n \"type\": \"number\",\n \"default\": 25,\n \"min\": 0,\n \"max\": 100,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"step\": 1\n },\n {\n \"id\": \"reverbTime\",\n \"name\": \"Reverb Time\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.05,\n \"max\": 0.95,\n \"step\": 0.01\n },\n {\n \"id\": \"hfDamping\",\n \"name\": \"HF Damping\",\n \"type\": \"number\",\n \"min\": 40,\n \"max\": 1000,\n \"default\": 100,\n \"conversion\": \"LOGFREQ\"\n },\n {\n \"id\": \"inputAllpassCoeff\",\n \"name\": \"Input Allpass\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.05,\n \"max\": 0.95,\n \"step\": 0.01\n },\n {\n \"id\": \"delayAllpassCoeff\",\n \"name\": \"Delay Allpass\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.05,\n \"max\": 0.95,\n \"step\": 0.01\n },\n {\n \"id\": \"hfLoss\",\n \"name\": \"HF Loss\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"High-frequency loss applied in the reverb loops. 1.0 = full HF, 0.0 = maximum loss.\"\n },\n {\n \"id\": \"lfoRate\",\n \"name\": \"LFO Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 0.25,\n \"min\": 0.05,\n \"max\": 2.0,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Frequency of the LFO modulation in Hz.\",\n \"step\": 0.01\n }\n ],\n \"memories\": [\n { \"id\": \"pdel\", \"size\": 3276 },\n { \"id\": \"tdel\", \"size\": 4000 },\n { \"id\": \"ap1\", \"size\": 473 },\n { \"id\": \"ap2\", \"size\": 536 },\n { \"id\": \"ap3\", \"size\": 667 },\n { \"id\": \"ap4\", \"size\": 791 },\n { \"id\": \"tap1\", \"size\": 452 },\n { \"id\": \"tap2\", \"size\": 561 },\n { \"id\": \"lap1a\", \"size\": 878 },\n { \"id\": \"lap1b\", \"size\": 1287 },\n { \"id\": \"d1\", \"size\": 1536 },\n { \"id\": \"lap2a\", \"size\": 968 },\n { \"id\": \"lap2b\", \"size\": 1367 },\n { \"id\": \"d2\", \"size\": 1891 },\n { \"id\": \"lap3a\", \"size\": 678 },\n { \"id\": \"lap3b\", \"size\": 1127 },\n { \"id\": \"d3\", \"size\": 1936 },\n { \"id\": \"lap4a\", \"size\": 1263 },\n { \"id\": \"lap4b\", \"size\": 1198 },\n { \"id\": \"d4\", \"size\": 1781 }\n ],\n \"registers\": [\n \"apout\", \"temp\", \"kd\", \"rt_cv\", \"lp1\", \"lp2\", \"lp3\", \"lp4\", \"hp1\", \"hp2\", \"tlp\"\n ]\n}\n---\n@section init\n@if pinConnected(input)\n; Room Reverb init\nskp run, room_reverb_init\nwrax ${reg.lp1}, 0.0\nwrax ${reg.lp2}, 0.0\nwrax ${reg.hp1}, 0.0\nwrax ${reg.hp2}, 0.0\nwrax ${reg.tlp}, 0.0\nwlds SIN0, ${lfoRate}, 100\nroom_reverb_init:\n@endif\n\n@section main\n@if pinConnected(input)\n\n; Room Reverb\n\n; Evaluate Control Voltages globally\n@cv hf_loss\nwrax ${reg.kd}, 0.0\n\n@cv reverb_time\nwrax ${reg.rt_cv}, 0.0\n\n@cv pre_delay\nsof 0.1, 0.0\nwrax ADDR_PTR, 0.0\n\n; Feed input to pre-delay\nrdax ${input.input}, ${inputGain}\nwra ${mem.pdel}, 0.0\n\n; Read pre-delay and write to tap delay\nrmpa 1.0\nwra ${mem.tdel}, 1.0\n\n; 4 input allpass filters\nrda ${mem.ap1}^, ${inputAllpassCoeff}\nwrap ${mem.ap1}, -${inputAllpassCoeff}\nrda ${mem.ap2}^, ${inputAllpassCoeff}\nwrap ${mem.ap2}, -${inputAllpassCoeff}\nrda ${mem.ap3}^, ${inputAllpassCoeff}\nwrap ${mem.ap3}, -${inputAllpassCoeff}\nrda ${mem.ap4}^, ${inputAllpassCoeff}\nwrap ${mem.ap4}, -${inputAllpassCoeff}\nwrax ${reg.apout}, 0.0\n\n; Delay loop 1\nrda ${mem.d4}^, ${reverbTime}\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap1a}^, ${delayAllpassCoeff}\nwrap ${mem.lap1a}, -${delayAllpassCoeff}\nrda ${mem.lap1b}^, -${delayAllpassCoeff}\nwrap ${mem.lap1b}, ${delayAllpassCoeff}\nrdfx ${reg.hp1}, ${hfDamping}\nwrhx ${reg.hp1}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp1}, 0.5\nwrhx ${reg.lp1}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d1}, 0.0\n\n; Delay loop 2\nrda ${mem.d1}^, -${reverbTime}\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap2a}^, ${delayAllpassCoeff}\nwrap ${mem.lap2a}, -${delayAllpassCoeff}\nrda ${mem.lap2b}^, ${delayAllpassCoeff}\nwrap ${mem.lap2b}, -${delayAllpassCoeff}\nrdfx ${reg.hp2}, ${hfDamping}\nwrhx ${reg.hp2}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp2}, 0.5\nwrhx ${reg.lp2}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d2}, 0.0\n\n; Delay loop 3\nrda ${mem.d2}^, -1.0\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap3a}^, ${delayAllpassCoeff}\nwrap ${mem.lap3a}, -${delayAllpassCoeff}\nrda ${mem.lap3b}^, ${delayAllpassCoeff}\nwrap ${mem.lap3b}, -${delayAllpassCoeff}\nrdfx ${reg.hp2}, 0.05\nwrhx ${reg.hp2}, -0.5\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp3}, 0.5\nwrhx ${reg.lp3}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d3}, 0.0\n\n; Delay loop 4\nrda ${mem.d3}^, -1.0\nmulx ${reg.rt_cv}\nrdax ${reg.apout}, 1.0\nrda ${mem.lap4a}^, ${delayAllpassCoeff}\nwrap ${mem.lap4a}, -${delayAllpassCoeff}\nrda ${mem.lap4b}^, ${delayAllpassCoeff}\nwrap ${mem.lap4b}, -${delayAllpassCoeff}\nwrax ${reg.temp}, -1.0\nrdfx ${reg.lp4}, 0.5\nwrhx ${reg.lp4}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.d4}, 0.0\n\n; Tap delay processing\nrda ${mem.tdel}+100, 1.0\nrda ${mem.tap1}^, 0.5\nwrap ${mem.tap1}, -0.5\nwrax ${reg.temp}, 1.0\nrdfx ${reg.tlp}, 0.1\nwrhx ${reg.tlp}, -1.0\nmulx ${reg.kd}\nrdax ${reg.temp}, 1.0\nwra ${mem.tdel}+101, 0.0\n\nrda ${mem.tdel}+1000, 1.0\nrda ${mem.tap2}^, 0.5\nwrap ${mem.tap2}, -0.5\nwra ${mem.tdel}+1001, 0.0\n\n; Left output mix\nrda ${mem.tdel}+701, 0.7\nrda ${mem.tdel}+956, 0.6\nrda ${mem.tdel}+409, 0.5\nrda ${mem.tdel}+1323, 0.4\n\n@if pinConnected(outputR)\nrda ${mem.d1}, 1.5\n@else\nrda ${mem.d1}^, 0.7\nrda ${mem.d2}^, 0.8\n@endif\n@if pinConnected(outputL)\nwrax ${output.outputL}, 0.0\n@else\nwrax ADDR_PTR, 0.0\n@endif\n\n; Right output mix\n@if pinConnected(outputR)\nrda ${mem.tdel}+582, 0.7\nrda ${mem.tdel}+956, 0.6\nrda ${mem.tdel}+1047, 0.5\nrda ${mem.tdel}+1323, 0.4\nrda ${mem.d3}, 1.5\nwrax ${output.outputR}, 0.0\n@endif\n\n; LFO chorus modulation\ncho rda, SIN0, REG|COMPC, ${mem.lap1b}+100\ncho rda, SIN0, SIN, ${mem.lap1b}+101\nwra ${mem.lap1b}+200, 0.0\n\ncho rda, SIN0, COS|REG|COMPC, ${mem.lap3b}+100\ncho rda, SIN0, COS, ${mem.lap3b}+101\nwra ${mem.lap3b}+200, 0.0\n\n@else\n; Room Reverb (no input connected)\n@endif\n"
|
|
2655
2655
|
},
|
|
2656
2656
|
{
|
|
2657
2657
|
"type": "effects.smear",
|
|
@@ -2717,8 +2717,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2717
2717
|
"ap_out",
|
|
2718
2718
|
"ap_temp"
|
|
2719
2719
|
],
|
|
2720
|
-
"template": "; Spectral Smear - Multi-tap Diffusion (Stable Unity Gain)\
|
|
2721
|
-
"_rawAtl": "---\
|
|
2720
|
+
"template": "; Spectral Smear - Multi-tap Diffusion (Stable Unity Gain)\n\n@section main\n@if pinConnected(input)\n; Load feedback (parameter JSON already caps max at 0.65 for stability)\n@cv density\nwrax ${reg.fb_reg}, 0.0\n\nrdax ${input.input}, 1.0\nwrax ${reg.ap_in}, 1.0\n\n; --- AP Stages (Discrete Unrolled All-pass) ---\n; Stage 1\nrda ${mem.ap1}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap1}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 2\nrda ${mem.ap2}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap2}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 3\nrda ${mem.ap3}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap3}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 4\nrda ${mem.ap4}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap4}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\n\n; Output (Unity Gain)\nwrax ${output.out}, 0.0\n@endif",
|
|
2721
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.smear\",\n \"name\": \"Spectral Smear\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"description\": \"Diffusion bank of prime-numbered all-pass filters.\",\n \"color\": \"#6f24f2\",\n \"inputs\": [\n { \"id\": \"input\", \"name\": \"Audio In\", \"type\": \"audio\" },\n { \"id\": \"density\", \"name\": \"Density\", \"type\": \"control\", \"required\": false, \"parameter\": \"feedback\" }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Audio Out\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"feedback\",\n \"name\": \"Density (Feedback)\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 0.65,\n \"step\": 0.01,\n \"description\": \"Density of the smear. Capped at 0.65 for stability.\"\n }\n ],\n \"memories\": [\n { \"id\": \"ap1\", \"size\": 151 },\n { \"id\": \"ap2\", \"size\": 211 },\n { \"id\": \"ap3\", \"size\": 331 },\n { \"id\": \"ap4\", \"size\": 439 }\n ],\n \"registers\": [ \"fb_reg\", \"ap_in\", \"ap_out\", \"ap_temp\" ]\n}\n---\n; Spectral Smear - Multi-tap Diffusion (Stable Unity Gain)\n\n@section main\n@if pinConnected(input)\n; Load feedback (parameter JSON already caps max at 0.65 for stability)\n@cv density\nwrax ${reg.fb_reg}, 0.0\n\nrdax ${input.input}, 1.0\nwrax ${reg.ap_in}, 1.0\n\n; --- AP Stages (Discrete Unrolled All-pass) ---\n; Stage 1\nrda ${mem.ap1}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap1}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 2\nrda ${mem.ap2}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap2}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 3\nrda ${mem.ap3}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap3}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\nwrax ${reg.ap_in}, 0.0\n\n; Stage 4\nrda ${mem.ap4}#, 1.0\nwrax ${reg.ap_out}, -1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_in}, 1.0\nwra ${mem.ap4}, 1.0\nmulx ${reg.fb_reg}\nrdax ${reg.ap_out}, 1.0\n\n; Output (Unity Gain)\nwrax ${output.out}, 0.0\n@endif\n"
|
|
2722
2722
|
},
|
|
2723
2723
|
{
|
|
2724
2724
|
"type": "effects.springreverb",
|
|
@@ -2984,8 +2984,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
2984
2984
|
"spring",
|
|
2985
2985
|
"temp"
|
|
2986
2986
|
],
|
|
2987
|
-
"template": "@section init\
|
|
2988
|
-
"_rawAtl": "---\
|
|
2987
|
+
"template": "@section init\n; Spring Reverb\nskp RUN, springreverb_init_end\nwlds SIN0, 15, 40 ; LFO for reverb smoothing\nspringreverb_init_end:\n\n@section main\n; Spring Reverb\n\n; Calculate tone coefficient (kfil) from CV input or parameter\n@if pinConnected(toneCV)\nrdax ${input.toneCV}, 1.0 ; Read tone from CV input\nsof 0.4, 0.1 ; Map [0,1] to [0.1,0.5]\n@else\nsof 0.0, ${tone} ; Read tone from parameter\n@endif\nwrax ${reg.kfil}, 0.0 ; Write tone coefficient\n\n; Calculate reverb time (KRT) from CV input or parameter\n@if pinConnected(reverbTimeCV)\nrdax ${input.reverbTimeCV}, 1.0 ; Read reverb time from CV input\nsof 0.15, 0.7 ; Map [0,1] to [0.7,0.85]\n@else\nsof 0.0, ${reverbTime} ; Read reverb time from parameter\n@endif\nwrax ${reg.KRT}, 0.0 ; Write reverb time\n\n; Sum inputs to mono\n@if pinConnected(in)\nrdax ${input.in}, 1.0\n@else\nsof 0.0, 0.0\n@endif\nwrax ${reg.mono}, 1.0 ; Save and keep in ACC\n\n; Abbey Road EMI RS127 pre-reverb filter\nrdfx ${reg.lpf1}, 0.853 ; 10kHz LPF\nwrlx ${reg.lpf1}, -0.5 ; Shelving LPF\nrdfx ${reg.hpf1}, 0.109 ; 600Hz HPF\nwrhx ${reg.hpf1}, -0.5 ; Shelving HPF\nwrax ${reg.revin}, 1.0 ; Save filtered signal\n\n; Reverb loop 1\nrda ${mem.d1}#, 1.0 ; Get 1st delay output\nmulx ${reg.KRT} ; Apply reverb time\nrdfx ${reg.lp1}, 0.55 ; Shelving lowpass\nwrlx ${reg.lp1}, -1.0\nrda ${mem.lap1a}#, 0.6 ; Reverb allpass 1a\nwrap ${mem.lap1a}, -0.6\nrda ${mem.lap1b}#, 0.6 ; Reverb allpass 1b\nwrap ${mem.lap1b}, -0.6\nrdax ${reg.revin}, 1.0 ; Add filtered input\nwra ${mem.d2}, 0.0 ; Put in 2nd spring delay\n\n; Reverb loop 2\nrda ${mem.d2}#, 1.0 ; Get 2nd delay output\nmulx ${reg.KRT} ; Apply reverb time\nrdfx ${reg.lp2}, 0.55 ; Shelving lowpass\nwrlx ${reg.lp2}, -1.0\nrda ${mem.lap2a}#, 0.6 ; Reverb allpass 2a\nwrap ${mem.lap2a}, -0.6\nrda ${mem.lap2b}#, 0.6 ; Reverb allpass 2b\nwrap ${mem.lap2b}, -0.6\nrdax ${reg.revin}, 1.0 ; Add filtered input\nwra ${mem.d1}, 0.0 ; Put in 1st spring delay\n\n; Chirp filter (spring dispersion)\nrdax ${reg.lp1}, 1.0\nrdax ${reg.lp2}, 1.0\n\n; Generated chirp allpass filters\n@if ${chirpFilters} > 0\nrda ${mem.ap1}^, -0.6\nwrap ${mem.ap1}, 0.6\n@endif\n@if ${chirpFilters} > 1\nrda ${mem.ap2}^, -0.6\nwrap ${mem.ap2}, 0.6\n@endif\n@if ${chirpFilters} > 2\nrda ${mem.ap3}^, -0.6\nwrap ${mem.ap3}, 0.6\n@endif\n@if ${chirpFilters} > 3\nrda ${mem.ap4}^, -0.6\nwrap ${mem.ap4}, 0.6\n@endif\n@if ${chirpFilters} > 4\nrda ${mem.ap5}^, -0.6\nwrap ${mem.ap5}, 0.6\n@endif\n@if ${chirpFilters} > 5\nrda ${mem.ap6}^, -0.6\nwrap ${mem.ap6}, 0.6\n@endif\n@if ${chirpFilters} > 6\nrda ${mem.ap7}^, -0.6\nwrap ${mem.ap7}, 0.6\n@endif\n@if ${chirpFilters} > 7\nrda ${mem.ap8}^, -0.6\nwrap ${mem.ap8}, 0.6\n@endif\n@if ${chirpFilters} > 8\nrda ${mem.ap9}^, -0.6\nwrap ${mem.ap9}, 0.6\n@endif\n@if ${chirpFilters} > 9\nrda ${mem.ap10}^, -0.6\nwrap ${mem.ap10}, 0.6\n@endif\n@if ${chirpFilters} > 10\nrda ${mem.ap11}^, -0.6\nwrap ${mem.ap11}, 0.6\n@endif\n@if ${chirpFilters} > 11\nrda ${mem.ap12}^, -0.6\nwrap ${mem.ap12}, 0.6\n@endif\n@if ${chirpFilters} > 12\nrda ${mem.ap13}^, -0.6\nwrap ${mem.ap13}, 0.6\n@endif\n@if ${chirpFilters} > 13\nrda ${mem.ap14}^, -0.6\nwrap ${mem.ap14}, 0.6\n@endif\n@if ${chirpFilters} > 14\nrda ${mem.ap15}^, -0.6\nwrap ${mem.ap15}, 0.6\n@endif\n@if ${chirpFilters} > 15\nrda ${mem.ap16}^, -0.6\nwrap ${mem.ap16}, 0.6\n@endif\n@if ${chirpFilters} > 16\nrda ${mem.ap17}^, -0.6\nwrap ${mem.ap17}, 0.6\n@endif\n@if ${chirpFilters} > 17\nrda ${mem.ap18}^, -0.6\nwrap ${mem.ap18}, 0.6\n@endif\n@if ${chirpFilters} > 18\nrda ${mem.ap19}^, -0.6\nwrap ${mem.ap19}, 0.6\n@endif\n@if ${chirpFilters} > 19\nrda ${mem.ap20}^, -0.6\nwrap ${mem.ap20}, 0.6\n@endif\n@if ${chirpFilters} > 20\nrda ${mem.ap21}^, -0.6\nwrap ${mem.ap21}, 0.6\n@endif\n@if ${chirpFilters} > 21\nrda ${mem.ap22}^, -0.6\nwrap ${mem.ap22}, 0.6\n@endif\n@if ${chirpFilters} > 22\nrda ${mem.ap23}^, -0.6\nwrap ${mem.ap23}, 0.6\n@endif\n@if ${chirpFilters} > 23\nrda ${mem.ap24}^, -0.6\nwrap ${mem.ap24}, 0.6\n@endif\n@if ${chirpFilters} > 24\nrda ${mem.ap25}^, -0.6\nwrap ${mem.ap25}, 0.6\n@endif\n@if ${chirpFilters} > 25\nrda ${mem.ap26}^, -0.6\nwrap ${mem.ap26}, 0.6\n@endif\n@if ${chirpFilters} > 26\nrda ${mem.ap27}^, -0.6\nwrap ${mem.ap27}, 0.6\n@endif\n@if ${chirpFilters} > 27\nrda ${mem.ap28}^, -0.6\nwrap ${mem.ap28}, 0.6\n@endif\n@if ${chirpFilters} > 28\nrda ${mem.ap29}^, -0.6\nwrap ${mem.ap29}, 0.6\n@endif\n@if ${chirpFilters} > 29\nrda ${mem.ap30}^, -0.6\nwrap ${mem.ap30}, 0.6\n@endif\n@if ${chirpFilters} > 30\nrda ${mem.ap31}^, -0.6\nwrap ${mem.ap31}, 0.6\n@endif\n@if ${chirpFilters} > 31\nrda ${mem.ap32}^, -0.6\nwrap ${mem.ap32}, 0.6\n@endif\n@if ${chirpFilters} > 32\nrda ${mem.ap33}^, -0.6\nwrap ${mem.ap33}, 0.6\n@endif\n@if ${chirpFilters} > 33\nrda ${mem.ap34}^, -0.6\nwrap ${mem.ap34}, 0.6\n@endif\n@if ${chirpFilters} > 34\nrda ${mem.ap35}^, -0.6\nwrap ${mem.ap35}, 0.6\n@endif\n@if ${chirpFilters} > 35\nrda ${mem.ap36}^, -0.6\nwrap ${mem.ap36}, 0.6\n@endif\n@if ${chirpFilters} > 36\nrda ${mem.ap37}^, -0.6\nwrap ${mem.ap37}, 0.6\n@endif\n@if ${chirpFilters} > 37\nrda ${mem.ap38}^, -0.6\nwrap ${mem.ap38}, 0.6\n@endif\n@if ${chirpFilters} > 38\nrda ${mem.ap39}^, -0.6\nwrap ${mem.ap39}, 0.6\n@endif\n@if ${chirpFilters} > 39\nrda ${mem.ap40}^, -0.6\nwrap ${mem.ap40}, 0.6\n@endif\n@if ${chirpFilters} > 40\nrda ${mem.ap41}^, -0.6\nwrap ${mem.ap41}, 0.6\n@endif\n\n; Post-reverb tone shaping\nrdax ${reg.temp}, -1.0\nmulx ${reg.kfil}\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp}, 1.0\nwrax ${reg.spring}, 0.0\n\n; Output 100% wet signal\nrdax ${reg.spring}, 1.0\nwrax ${output.out}, 0.0\n\n; Smooth reverb with LFO modulation\ncho RDA, SIN0, SIN|REG|COMPC, ${mem.lap1b}+25\ncho RDA, SIN0, SIN, ${mem.lap1b}+26\nwra ${mem.lap1b}+50, 0.0\ncho RDA, SIN0, COS|REG|COMPC, ${mem.lap2b}+25\ncho RDA, SIN0, COS, ${mem.lap2b}+26\nwra ${mem.lap2b}+50, 0.0",
|
|
2988
|
+
"_rawAtl": "---\n{\n \"type\": \"effects.springreverb\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"name\": \"Spring Reverb\",\n \"description\": \"Fender-style spring reverb with RS127 filtering\",\n \"color\": \"#7100FC\",\n \"inputs\": [\n { \"id\": \"in\", \"name\": \"Input\", \"type\": \"audio\" },\n { \"id\": \"toneCV\", \"name\": \"Tone\", \"type\": \"control\", \"required\": false },\n { \"id\": \"reverbTimeCV\", \"name\": \"Reverb Time\", \"type\": \"control\", \"required\": false }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Output\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"tone\",\n \"name\": \"Tone\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01\n },\n {\n \"id\": \"reverbTime\",\n \"name\": \"Reverb Time\",\n \"type\": \"number\",\n \"default\": 0.775,\n \"min\": 0.7,\n \"max\": 0.85,\n \"step\": 0.01\n },\n {\n \"id\": \"chirpFilters\",\n \"name\": \"Chirp Filters\",\n \"type\": \"number\",\n \"default\": 37,\n \"min\": 7,\n \"max\": 41,\n \"step\": 1\n }\n ],\n \"memories\": [\n { \"id\": \"lap1a\", \"size\": 404 },\n { \"id\": \"lap1b\", \"size\": 967 },\n { \"id\": \"d1\", \"size\": 1445 },\n { \"id\": \"lap2a\", \"size\": 608 },\n { \"id\": \"lap2b\", \"size\": 893 },\n { \"id\": \"d2\", \"size\": 1013 },\n { \"id\": \"ap1\", \"size\": 5 },\n { \"id\": \"ap2\", \"size\": 5 },\n { \"id\": \"ap3\", \"size\": 5 },\n { \"id\": \"ap4\", \"size\": 5 },\n { \"id\": \"ap5\", \"size\": 5 },\n { \"id\": \"ap6\", \"size\": 5 },\n { \"id\": \"ap7\", \"size\": 5 },\n { \"id\": \"ap8\", \"size\": 6 },\n { \"id\": \"ap9\", \"size\": 6 },\n { \"id\": \"ap10\", \"size\": 6 },\n { \"id\": \"ap11\", \"size\": 6 },\n { \"id\": \"ap12\", \"size\": 6 },\n { \"id\": \"ap13\", \"size\": 6 },\n { \"id\": \"ap14\", \"size\": 6 },\n { \"id\": \"ap15\", \"size\": 6 },\n { \"id\": \"ap16\", \"size\": 6 },\n { \"id\": \"ap17\", \"size\": 6 },\n { \"id\": \"ap18\", \"size\": 6 },\n { \"id\": \"ap19\", \"size\": 6 },\n { \"id\": \"ap20\", \"size\": 6 },\n { \"id\": \"ap21\", \"size\": 6 },\n { \"id\": \"ap22\", \"size\": 7 },\n { \"id\": \"ap23\", \"size\": 7 },\n { \"id\": \"ap24\", \"size\": 7 },\n { \"id\": \"ap25\", \"size\": 7 },\n { \"id\": \"ap26\", \"size\": 7 },\n { \"id\": \"ap27\", \"size\": 7 },\n { \"id\": \"ap28\", \"size\": 7 },\n { \"id\": \"ap29\", \"size\": 7 },\n { \"id\": \"ap30\", \"size\": 7 },\n { \"id\": \"ap31\", \"size\": 7 },\n { \"id\": \"ap32\", \"size\": 7 },\n { \"id\": \"ap33\", \"size\": 7 },\n { \"id\": \"ap34\", \"size\": 7 },\n { \"id\": \"ap35\", \"size\": 7 },\n { \"id\": \"ap36\", \"size\": 8 },\n { \"id\": \"ap37\", \"size\": 8 },\n { \"id\": \"ap38\", \"size\": 8 },\n { \"id\": \"ap39\", \"size\": 8 },\n { \"id\": \"ap40\", \"size\": 8 },\n { \"id\": \"ap41\", \"size\": 8 }\n ],\n \"registers\": [\n \"mono\", \"lp1\", \"lp2\", \"KRT\", \"revin\", \"kfil\", \"lpf1\", \"hpf1\", \"spring\", \"temp\"\n ]\n}\n---\n@section init\n; Spring Reverb\nskp RUN, springreverb_init_end\nwlds SIN0, 15, 40 ; LFO for reverb smoothing\nspringreverb_init_end:\n\n@section main\n; Spring Reverb\n\n; Calculate tone coefficient (kfil) from CV input or parameter\n@if pinConnected(toneCV)\nrdax ${input.toneCV}, 1.0 ; Read tone from CV input\nsof 0.4, 0.1 ; Map [0,1] to [0.1,0.5]\n@else\nsof 0.0, ${tone} ; Read tone from parameter\n@endif\nwrax ${reg.kfil}, 0.0 ; Write tone coefficient\n\n; Calculate reverb time (KRT) from CV input or parameter\n@if pinConnected(reverbTimeCV)\nrdax ${input.reverbTimeCV}, 1.0 ; Read reverb time from CV input\nsof 0.15, 0.7 ; Map [0,1] to [0.7,0.85]\n@else\nsof 0.0, ${reverbTime} ; Read reverb time from parameter\n@endif\nwrax ${reg.KRT}, 0.0 ; Write reverb time\n\n; Sum inputs to mono\n@if pinConnected(in)\nrdax ${input.in}, 1.0\n@else\nsof 0.0, 0.0\n@endif\nwrax ${reg.mono}, 1.0 ; Save and keep in ACC\n\n; Abbey Road EMI RS127 pre-reverb filter\nrdfx ${reg.lpf1}, 0.853 ; 10kHz LPF\nwrlx ${reg.lpf1}, -0.5 ; Shelving LPF\nrdfx ${reg.hpf1}, 0.109 ; 600Hz HPF\nwrhx ${reg.hpf1}, -0.5 ; Shelving HPF\nwrax ${reg.revin}, 1.0 ; Save filtered signal\n\n; Reverb loop 1\nrda ${mem.d1}#, 1.0 ; Get 1st delay output\nmulx ${reg.KRT} ; Apply reverb time\nrdfx ${reg.lp1}, 0.55 ; Shelving lowpass\nwrlx ${reg.lp1}, -1.0\nrda ${mem.lap1a}#, 0.6 ; Reverb allpass 1a\nwrap ${mem.lap1a}, -0.6\nrda ${mem.lap1b}#, 0.6 ; Reverb allpass 1b\nwrap ${mem.lap1b}, -0.6\nrdax ${reg.revin}, 1.0 ; Add filtered input\nwra ${mem.d2}, 0.0 ; Put in 2nd spring delay\n\n; Reverb loop 2\nrda ${mem.d2}#, 1.0 ; Get 2nd delay output\nmulx ${reg.KRT} ; Apply reverb time\nrdfx ${reg.lp2}, 0.55 ; Shelving lowpass\nwrlx ${reg.lp2}, -1.0\nrda ${mem.lap2a}#, 0.6 ; Reverb allpass 2a\nwrap ${mem.lap2a}, -0.6\nrda ${mem.lap2b}#, 0.6 ; Reverb allpass 2b\nwrap ${mem.lap2b}, -0.6\nrdax ${reg.revin}, 1.0 ; Add filtered input\nwra ${mem.d1}, 0.0 ; Put in 1st spring delay\n\n; Chirp filter (spring dispersion)\nrdax ${reg.lp1}, 1.0\nrdax ${reg.lp2}, 1.0\n\n; Generated chirp allpass filters\n@if ${chirpFilters} > 0\nrda ${mem.ap1}^, -0.6\nwrap ${mem.ap1}, 0.6\n@endif\n@if ${chirpFilters} > 1\nrda ${mem.ap2}^, -0.6\nwrap ${mem.ap2}, 0.6\n@endif\n@if ${chirpFilters} > 2\nrda ${mem.ap3}^, -0.6\nwrap ${mem.ap3}, 0.6\n@endif\n@if ${chirpFilters} > 3\nrda ${mem.ap4}^, -0.6\nwrap ${mem.ap4}, 0.6\n@endif\n@if ${chirpFilters} > 4\nrda ${mem.ap5}^, -0.6\nwrap ${mem.ap5}, 0.6\n@endif\n@if ${chirpFilters} > 5\nrda ${mem.ap6}^, -0.6\nwrap ${mem.ap6}, 0.6\n@endif\n@if ${chirpFilters} > 6\nrda ${mem.ap7}^, -0.6\nwrap ${mem.ap7}, 0.6\n@endif\n@if ${chirpFilters} > 7\nrda ${mem.ap8}^, -0.6\nwrap ${mem.ap8}, 0.6\n@endif\n@if ${chirpFilters} > 8\nrda ${mem.ap9}^, -0.6\nwrap ${mem.ap9}, 0.6\n@endif\n@if ${chirpFilters} > 9\nrda ${mem.ap10}^, -0.6\nwrap ${mem.ap10}, 0.6\n@endif\n@if ${chirpFilters} > 10\nrda ${mem.ap11}^, -0.6\nwrap ${mem.ap11}, 0.6\n@endif\n@if ${chirpFilters} > 11\nrda ${mem.ap12}^, -0.6\nwrap ${mem.ap12}, 0.6\n@endif\n@if ${chirpFilters} > 12\nrda ${mem.ap13}^, -0.6\nwrap ${mem.ap13}, 0.6\n@endif\n@if ${chirpFilters} > 13\nrda ${mem.ap14}^, -0.6\nwrap ${mem.ap14}, 0.6\n@endif\n@if ${chirpFilters} > 14\nrda ${mem.ap15}^, -0.6\nwrap ${mem.ap15}, 0.6\n@endif\n@if ${chirpFilters} > 15\nrda ${mem.ap16}^, -0.6\nwrap ${mem.ap16}, 0.6\n@endif\n@if ${chirpFilters} > 16\nrda ${mem.ap17}^, -0.6\nwrap ${mem.ap17}, 0.6\n@endif\n@if ${chirpFilters} > 17\nrda ${mem.ap18}^, -0.6\nwrap ${mem.ap18}, 0.6\n@endif\n@if ${chirpFilters} > 18\nrda ${mem.ap19}^, -0.6\nwrap ${mem.ap19}, 0.6\n@endif\n@if ${chirpFilters} > 19\nrda ${mem.ap20}^, -0.6\nwrap ${mem.ap20}, 0.6\n@endif\n@if ${chirpFilters} > 20\nrda ${mem.ap21}^, -0.6\nwrap ${mem.ap21}, 0.6\n@endif\n@if ${chirpFilters} > 21\nrda ${mem.ap22}^, -0.6\nwrap ${mem.ap22}, 0.6\n@endif\n@if ${chirpFilters} > 22\nrda ${mem.ap23}^, -0.6\nwrap ${mem.ap23}, 0.6\n@endif\n@if ${chirpFilters} > 23\nrda ${mem.ap24}^, -0.6\nwrap ${mem.ap24}, 0.6\n@endif\n@if ${chirpFilters} > 24\nrda ${mem.ap25}^, -0.6\nwrap ${mem.ap25}, 0.6\n@endif\n@if ${chirpFilters} > 25\nrda ${mem.ap26}^, -0.6\nwrap ${mem.ap26}, 0.6\n@endif\n@if ${chirpFilters} > 26\nrda ${mem.ap27}^, -0.6\nwrap ${mem.ap27}, 0.6\n@endif\n@if ${chirpFilters} > 27\nrda ${mem.ap28}^, -0.6\nwrap ${mem.ap28}, 0.6\n@endif\n@if ${chirpFilters} > 28\nrda ${mem.ap29}^, -0.6\nwrap ${mem.ap29}, 0.6\n@endif\n@if ${chirpFilters} > 29\nrda ${mem.ap30}^, -0.6\nwrap ${mem.ap30}, 0.6\n@endif\n@if ${chirpFilters} > 30\nrda ${mem.ap31}^, -0.6\nwrap ${mem.ap31}, 0.6\n@endif\n@if ${chirpFilters} > 31\nrda ${mem.ap32}^, -0.6\nwrap ${mem.ap32}, 0.6\n@endif\n@if ${chirpFilters} > 32\nrda ${mem.ap33}^, -0.6\nwrap ${mem.ap33}, 0.6\n@endif\n@if ${chirpFilters} > 33\nrda ${mem.ap34}^, -0.6\nwrap ${mem.ap34}, 0.6\n@endif\n@if ${chirpFilters} > 34\nrda ${mem.ap35}^, -0.6\nwrap ${mem.ap35}, 0.6\n@endif\n@if ${chirpFilters} > 35\nrda ${mem.ap36}^, -0.6\nwrap ${mem.ap36}, 0.6\n@endif\n@if ${chirpFilters} > 36\nrda ${mem.ap37}^, -0.6\nwrap ${mem.ap37}, 0.6\n@endif\n@if ${chirpFilters} > 37\nrda ${mem.ap38}^, -0.6\nwrap ${mem.ap38}, 0.6\n@endif\n@if ${chirpFilters} > 38\nrda ${mem.ap39}^, -0.6\nwrap ${mem.ap39}, 0.6\n@endif\n@if ${chirpFilters} > 39\nrda ${mem.ap40}^, -0.6\nwrap ${mem.ap40}, 0.6\n@endif\n@if ${chirpFilters} > 40\nrda ${mem.ap41}^, -0.6\nwrap ${mem.ap41}, 0.6\n@endif\n\n; Post-reverb tone shaping\nrdax ${reg.temp}, -1.0\nmulx ${reg.kfil}\nrdax ${reg.temp}, 1.0\nwrax ${reg.temp}, 1.0\nwrax ${reg.spring}, 0.0\n\n; Output 100% wet signal\nrdax ${reg.spring}, 1.0\nwrax ${output.out}, 0.0\n\n; Smooth reverb with LFO modulation\ncho RDA, SIN0, SIN|REG|COMPC, ${mem.lap1b}+25\ncho RDA, SIN0, SIN, ${mem.lap1b}+26\nwra ${mem.lap1b}+50, 0.0\ncho RDA, SIN0, COS|REG|COMPC, ${mem.lap2b}+25\ncho RDA, SIN0, COS, ${mem.lap2b}+26\nwra ${mem.lap2b}+50, 0.0\n"
|
|
2989
2989
|
},
|
|
2990
2990
|
{
|
|
2991
2991
|
"type": "filter.auto_wah",
|
|
@@ -3103,8 +3103,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3103
3103
|
"dry_val",
|
|
3104
3104
|
"temp"
|
|
3105
3105
|
],
|
|
3106
|
-
"template": "@section main\
|
|
3107
|
-
"_rawAtl": "---\
|
|
3106
|
+
"template": "@section main\n@if pinConnected(in)\n\n ; ======================================================\n ; Stage 0: Save dry signal\n ; ======================================================\n rdax ${input.in}, 1.0\n wrax ${reg.dry_val}, 0.0\n\n ; ======================================================\n ; Stage 1: Load CVs\n ; ======================================================\n @cv sensitivity_cv\n wrax ${reg.sens_reg}, 0.0\n\n @cv resonance_cv\n sof -1.0, 1.0 ; damp = 1 - resonance (high resonance → low damping)\n wrax ${reg.damp_reg}, 0.0\n\n @cv mix_cv\n wrax ${reg.mix_reg}, 0.0\n\n ; ======================================================\n ; Stage 2: Envelope Follower (Fast Attack, Slow Release)\n ; ======================================================\n rdax ${input.in}, 1.0\n sof 1.99, 0.0 ; 2x pre-boost for detection only — env reaches higher values at normal guitar levels\n absa\n rdax ${reg.env}, -1.0 ; ACC = |input| - env\n skp gez, ${local.ATK}\n ; Release path\n sof ${param.release}, 0.0\n skp run, ${local.UPD}\n${local.ATK}:\n sof ${param.attack}, 0.0\n${local.UPD}:\n rdax ${reg.env}, 1.0 ; ACC = delta + env = new env\n wrax ${reg.env}, 0.0\n\n ; ======================================================\n ; Stage 3: Compute Swept Frequency\n ; freq = base_freq + env * sensitivity\n ; ======================================================\n rdax ${reg.env}, 1.0\n mulx ${reg.sens_reg} ; ACC = env * sensitivity\n sof 1.0, ${param.base_freq} ; ACC = base_freq + env * sensitivity\n wrax ${reg.freq_reg}, 0.0\n\n ; ======================================================\n ; Stage 4: Chamberlin SVF — Bandpass output\n ; HP = input - lp - damp*bp\n ; bp_new = bp_old + F * HP\n ; lp_new = lp_old + F * bp_new\n ; ======================================================\n\n ; Compute (input - lp_old) and save as temp\n rdax ${input.in}, 1.0\n rdax ${reg.lp}, -1.0\n wrax ${reg.temp}, 0.0 ; temp = input - lp_old\n\n ; Compute HP = (input - lp_old) - damp * bp_old\n rdax ${reg.bp}, 1.0\n mulx ${reg.damp_reg} ; ACC = damp * bp_old\n rdax ${reg.temp}, -1.0 ; ACC = damp*bp_old - (input - lp_old)\n sof -1.0, 0.0 ; ACC = HP = (input - lp_old) - damp*bp_old\n\n ; bp_new = bp_old + F * HP\n mulx ${reg.freq_reg} ; ACC = F * HP\n rdax ${reg.bp}, 1.0 ; ACC = bp_old + F * HP\n wrax ${reg.bp}, 1.0 ; Save bp_new, keep in ACC\n\n ; lp_new = lp_old + F * bp_new\n mulx ${reg.freq_reg} ; ACC = F * bp_new\n rdax ${reg.lp}, 1.0 ; ACC = lp_old + F * bp_new\n wrax ${reg.lp}, 0.0 ; Save lp_new\n\n ; ======================================================\n ; Stage 5: Dry/Wet Mix\n ; out = dry + (wet - dry) * mix\n ; ======================================================\n rdax ${reg.bp}, 0.7 ; Bandpass: vowel/formant peak (dominant)\n rdax ${reg.lp}, 0.3 ; Lowpass: adds fundamental body — pure BP sounds thin\n rdax ${reg.dry_val}, -1.0 ; ACC = wet - dry\n mulx ${reg.mix_reg} ; ACC = (wet - dry) * mix\n rdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix\n wrax ${output.out}, 0.0\n\n@endif",
|
|
3107
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.auto_wah\",\n \"name\": \"Auto-Wah\",\n \"category\": \"Filter\",\n \"description\": \"Envelope-controlled resonant bandpass filter. Pick harder to open the filter — produces the talkbox-like vowel sweep made famous by the Living on a Prayer guitar intro.\",\n \"color\": \"#f26724\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"sensitivity_cv\",\n \"name\": \"Sensitivity\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"sensitivity\"\n },\n {\n \"id\": \"resonance_cv\",\n \"name\": \"Resonance\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"resonance\"\n },\n {\n \"id\": \"mix_cv\",\n \"name\": \"Mix\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"mix\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"base_freq\",\n \"name\": \"Base Freq\",\n \"type\": \"number\",\n \"default\": 300,\n \"min\": 100,\n \"max\": 1500,\n \"step\": 10,\n \"conversion\": \"SVFFREQ\",\n \"description\": \"Lowest filter frequency (at silence). Sweep rises above this on transients.\"\n },\n {\n \"id\": \"sensitivity\",\n \"name\": \"Sensitivity\",\n \"type\": \"number\",\n \"default\": 0.55,\n \"min\": 0.0,\n \"max\": 0.6,\n \"step\": 0.01,\n \"description\": \"How far the envelope opens the filter. Higher = wider vowel sweep.\"\n },\n {\n \"id\": \"resonance\",\n \"name\": \"Resonance\",\n \"type\": \"number\",\n \"default\": 0.82,\n \"min\": 0.0,\n \"max\": 0.97,\n \"step\": 0.01,\n \"description\": \"Filter Q / resonant peak. Higher values add the characteristic vowel quack.\"\n },\n {\n \"id\": \"attack\",\n \"name\": \"Attack\",\n \"type\": \"number\",\n \"default\": 0.08,\n \"min\": 0.01,\n \"max\": 0.5,\n \"step\": 0.01,\n \"description\": \"Envelope attack speed. Higher = faster response to pick transients.\"\n },\n {\n \"id\": \"release\",\n \"name\": \"Release\",\n \"type\": \"number\",\n \"default\": 0.004,\n \"min\": 0.001,\n \"max\": 0.05,\n \"step\": 0.001,\n \"description\": \"Envelope release speed. Lower = slower filter close after note ends.\"\n },\n {\n \"id\": \"mix\",\n \"name\": \"Dry/Wet Mix\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"env\",\n \"bp\",\n \"lp\",\n \"freq_reg\",\n \"damp_reg\",\n \"sens_reg\",\n \"mix_reg\",\n \"dry_val\",\n \"temp\"\n ]\n}\n---\n@section main\n@if pinConnected(in)\n\n ; ======================================================\n ; Stage 0: Save dry signal\n ; ======================================================\n rdax ${input.in}, 1.0\n wrax ${reg.dry_val}, 0.0\n\n ; ======================================================\n ; Stage 1: Load CVs\n ; ======================================================\n @cv sensitivity_cv\n wrax ${reg.sens_reg}, 0.0\n\n @cv resonance_cv\n sof -1.0, 1.0 ; damp = 1 - resonance (high resonance → low damping)\n wrax ${reg.damp_reg}, 0.0\n\n @cv mix_cv\n wrax ${reg.mix_reg}, 0.0\n\n ; ======================================================\n ; Stage 2: Envelope Follower (Fast Attack, Slow Release)\n ; ======================================================\n rdax ${input.in}, 1.0\n sof 1.99, 0.0 ; 2x pre-boost for detection only — env reaches higher values at normal guitar levels\n absa\n rdax ${reg.env}, -1.0 ; ACC = |input| - env\n skp gez, ${local.ATK}\n ; Release path\n sof ${param.release}, 0.0\n skp run, ${local.UPD}\n${local.ATK}:\n sof ${param.attack}, 0.0\n${local.UPD}:\n rdax ${reg.env}, 1.0 ; ACC = delta + env = new env\n wrax ${reg.env}, 0.0\n\n ; ======================================================\n ; Stage 3: Compute Swept Frequency\n ; freq = base_freq + env * sensitivity\n ; ======================================================\n rdax ${reg.env}, 1.0\n mulx ${reg.sens_reg} ; ACC = env * sensitivity\n sof 1.0, ${param.base_freq} ; ACC = base_freq + env * sensitivity\n wrax ${reg.freq_reg}, 0.0\n\n ; ======================================================\n ; Stage 4: Chamberlin SVF — Bandpass output\n ; HP = input - lp - damp*bp\n ; bp_new = bp_old + F * HP\n ; lp_new = lp_old + F * bp_new\n ; ======================================================\n\n ; Compute (input - lp_old) and save as temp\n rdax ${input.in}, 1.0\n rdax ${reg.lp}, -1.0\n wrax ${reg.temp}, 0.0 ; temp = input - lp_old\n\n ; Compute HP = (input - lp_old) - damp * bp_old\n rdax ${reg.bp}, 1.0\n mulx ${reg.damp_reg} ; ACC = damp * bp_old\n rdax ${reg.temp}, -1.0 ; ACC = damp*bp_old - (input - lp_old)\n sof -1.0, 0.0 ; ACC = HP = (input - lp_old) - damp*bp_old\n\n ; bp_new = bp_old + F * HP\n mulx ${reg.freq_reg} ; ACC = F * HP\n rdax ${reg.bp}, 1.0 ; ACC = bp_old + F * HP\n wrax ${reg.bp}, 1.0 ; Save bp_new, keep in ACC\n\n ; lp_new = lp_old + F * bp_new\n mulx ${reg.freq_reg} ; ACC = F * bp_new\n rdax ${reg.lp}, 1.0 ; ACC = lp_old + F * bp_new\n wrax ${reg.lp}, 0.0 ; Save lp_new\n\n ; ======================================================\n ; Stage 5: Dry/Wet Mix\n ; out = dry + (wet - dry) * mix\n ; ======================================================\n rdax ${reg.bp}, 0.7 ; Bandpass: vowel/formant peak (dominant)\n rdax ${reg.lp}, 0.3 ; Lowpass: adds fundamental body — pure BP sounds thin\n rdax ${reg.dry_val}, -1.0 ; ACC = wet - dry\n mulx ${reg.mix_reg} ; ACC = (wet - dry) * mix\n rdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix\n wrax ${output.out}, 0.0\n\n@endif\n"
|
|
3108
3108
|
},
|
|
3109
3109
|
{
|
|
3110
3110
|
"type": "filter.bbd_loss",
|
|
@@ -3150,8 +3150,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3150
3150
|
"lp2",
|
|
3151
3151
|
"k_coeff"
|
|
3152
3152
|
],
|
|
3153
|
-
"template": "; BBD Bucket Loss Filter\
|
|
3154
|
-
"_rawAtl": "---\
|
|
3153
|
+
"template": "; BBD Bucket Loss Filter\n; A 2-pole cascaded LPF (12dB/oct) where the coefficient tracks the Coupling input.\n; Fix: Cascaded structure for a much more visible 'analog' roll-off.\n\n@section main\n@if pinConnected(input)\n\n; 1. Calculate dynamic coefficient k from Coupling input\n@cv coupling\n; ACC has Coupling value (0 to 1). \n; Formula: k = 1.0 - (ACC * loss_base * 0.95)\n; But let's map it aggressively to 0.02 (very dark) to 0.9 (bright)\nsof -0.88, 0.9\nwrax ${reg.k_coeff}, 0.0\n\n; 2. First Stage (6dB/oct)\nrdax ${input.input}, 1.0\nrdax ${reg.lp1}, -1.0\nmulx ${reg.k_coeff}\nrdax ${reg.lp1}, 1.0\nwrax ${reg.lp1}, 0.0\n\n; 3. Second Stage (Total 12dB/oct)\nrdax ${reg.lp1}, 1.0\nrdax ${reg.lp2}, -1.0\nmulx ${reg.k_coeff}\nrdax ${reg.lp2}, 1.0\nwrax ${reg.lp2}, 1.0\n\n; 4. Final Output\nwrax ${output.out}, 0.0\n@endif",
|
|
3154
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.bbd_loss\",\n \"name\": \"BBD Bucket Loss\",\n \"category\": \"Filter\",\n \"description\": \"Dynamic 12dB/oct low-pass filter that mimics the fidelity loss of analog delay lines (BBD). Fix: Steeper cascade for more pronounced effect.\",\n \"color\": \"#24f26f\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Audio In\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"coupling\",\n \"name\": \"Time Coupling\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"loss_base\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Audio Out\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"loss_base\",\n \"name\": \"Max Loss\",\n \"type\": \"number\",\n \"default\": 0.85,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"How much high-frequency is lost at maximum delay time.\"\n }\n ],\n \"registers\": [\n \"lp1\",\n \"lp2\",\n \"k_coeff\"\n ]\n}\n---\n; BBD Bucket Loss Filter\n; A 2-pole cascaded LPF (12dB/oct) where the coefficient tracks the Coupling input.\n; Fix: Cascaded structure for a much more visible 'analog' roll-off.\n\n@section main\n@if pinConnected(input)\n\n; 1. Calculate dynamic coefficient k from Coupling input\n@cv coupling\n; ACC has Coupling value (0 to 1). \n; Formula: k = 1.0 - (ACC * loss_base * 0.95)\n; But let's map it aggressively to 0.02 (very dark) to 0.9 (bright)\nsof -0.88, 0.9\nwrax ${reg.k_coeff}, 0.0\n\n; 2. First Stage (6dB/oct)\nrdax ${input.input}, 1.0\nrdax ${reg.lp1}, -1.0\nmulx ${reg.k_coeff}\nrdax ${reg.lp1}, 1.0\nwrax ${reg.lp1}, 0.0\n\n; 3. Second Stage (Total 12dB/oct)\nrdax ${reg.lp1}, 1.0\nrdax ${reg.lp2}, -1.0\nmulx ${reg.k_coeff}\nrdax ${reg.lp2}, 1.0\nwrax ${reg.lp2}, 1.0\n\n; 4. Final Output\nwrax ${output.out}, 0.0\n@endif\n"
|
|
3155
3155
|
},
|
|
3156
3156
|
{
|
|
3157
3157
|
"type": "filter.hpf_1p",
|
|
@@ -3192,8 +3192,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3192
3192
|
"registers": [
|
|
3193
3193
|
"lpf1"
|
|
3194
3194
|
],
|
|
3195
|
-
"template": "@section header\
|
|
3196
|
-
"_rawAtl": "---\
|
|
3195
|
+
"template": "@section header\n@comment \"Generated from spincad source file HPF_RDFX.spincad\"\n\n@section main\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(${input.input})\n@if pinConnected(Frequency)\nrdax ${input.input}, ${freq}\nrdax ${reg.lpf1}, -${freq}\nmulx ${input.freqControl}\nrdax ${reg.lpf1}, 1.0\n@else\nrdax ${input.input}, 1.0\nrdfx ${reg.lpf1}, ${freq}\n@endif\nwrax ${reg.lpf1}, -1.0\n// do a lowpass filter then subtract that from the ${input.input}.\n// voila high pass filter!\nrdax ${input.input}, 1.0\nwrax ${output.output}, 0\n@endif",
|
|
3196
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.hpf_1p\",\n \"category\": \"Filter\",\n \"name\": \"1P HPF\",\n \"description\": \"1-pole high pass filter\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Input\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"freqControl\",\n \"name\": \"Frequency\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"freq\",\n \"name\": \"Frequency\",\n \"type\": \"number\",\n \"min\": 40,\n \"max\": 3500,\n \"default\": 100,\n \"conversion\": \"LOGFREQ\"\n }\n ],\n \"color\": \"#24f26f\",\n \"registers\": [\n \"lpf1\"\n ]\n}\n---\n@section header\n@comment \"Generated from spincad source file HPF_RDFX.spincad\"\n\n@section main\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(${input.input})\n@if pinConnected(Frequency)\nrdax ${input.input}, ${freq}\nrdax ${reg.lpf1}, -${freq}\nmulx ${input.freqControl}\nrdax ${reg.lpf1}, 1.0\n@else\nrdax ${input.input}, 1.0\nrdfx ${reg.lpf1}, ${freq}\n@endif\nwrax ${reg.lpf1}, -1.0\n// do a lowpass filter then subtract that from the ${input.input}.\n// voila high pass filter!\nrdax ${input.input}, 1.0\nwrax ${output.output}, 0\n@endif"
|
|
3197
3197
|
},
|
|
3198
3198
|
{
|
|
3199
3199
|
"type": "filter.lpf_1p",
|
|
@@ -3234,8 +3234,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3234
3234
|
"registers": [
|
|
3235
3235
|
"output"
|
|
3236
3236
|
],
|
|
3237
|
-
"template": "@section header\
|
|
3238
|
-
"_rawAtl": "---\
|
|
3237
|
+
"template": "@section header\n@comment \"Generated from spincad source file LPF_RDFX.spincad\"\n\n@section main\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(${input.input})\n@if pinConnected(Frequency)\nrdax ${input.input}, ${freq}\nrdax ${output.lpf1}, -${freq}\nmulx ${input.freqControl}\nrdax ${output.lpf1}, 1.0\n@else\nrdax ${input.input}, 1.0\nrdfx ${output.lpf1}, ${freq}\n@endif\nwrax ${output.lpf1}, 0\n@endif",
|
|
3238
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.lpf_1p\",\n \"category\": \"Filter\",\n \"name\": \"1P LPF\",\n \"description\": \"1-pole low pass filter\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Input\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"freqControl\",\n \"name\": \"Frequency\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"lpf1\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"freq\",\n \"name\": \"Frequency\",\n \"type\": \"number\",\n \"min\": 80,\n \"max\": 5000,\n \"default\": 100,\n \"conversion\": \"LOGFREQ\"\n }\n ],\n \"color\": \"#24f26f\",\n \"registers\": [\n \"output\"\n ]\n}\n---\n@section header\n@comment \"Generated from spincad source file LPF_RDFX.spincad\"\n\n@section main\n// variable - Name - low - high - multiplier - precision - option \n@if pinConnected(${input.input})\n@if pinConnected(Frequency)\nrdax ${input.input}, ${freq}\nrdax ${output.lpf1}, -${freq}\nmulx ${input.freqControl}\nrdax ${output.lpf1}, 1.0\n@else\nrdax ${input.input}, 1.0\nrdfx ${output.lpf1}, ${freq}\n@endif\nwrax ${output.lpf1}, 0\n@endif"
|
|
3239
3239
|
},
|
|
3240
3240
|
{
|
|
3241
3241
|
"type": "filter.shelving_hpf",
|
|
@@ -3292,8 +3292,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3292
3292
|
"hpf_state",
|
|
3293
3293
|
"temp"
|
|
3294
3294
|
],
|
|
3295
|
-
"template": "; Shelving HPF\
|
|
3296
|
-
"_rawAtl": "---\
|
|
3295
|
+
"template": "; Shelving HPF\nrdax ${input.in}, 1.0\n\n@if pinConnected(shelf_ctrl)\n; Shelf modulated by control input\n@comment \"Dynamic shelf control\"\nwrax ${reg.temp}, -(1.0 - ${shelf})\nrdfx ${reg.hpf_state}, ${frequency}\nwrlx ${reg.hpf_state}, -1.0\nmulx ${input.shelf_ctrl}\nrdax ${reg.temp}, 1.0\n@else\n; Fixed shelf depth\nrdfx ${reg.hpf_state}, ${frequency}\nwrhx ${reg.hpf_state}, -(1.0 - ${shelf})\n@endif\n\nwrax ${output.out}, 0.0",
|
|
3296
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.shelving_hpf\",\n \"name\": \"Shelving HPF\",\n \"category\": \"Filter\",\n \"description\": \"High-pass filter with adjustable shelf depth\",\n \"color\": \"#24f26f\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"shelf_ctrl\",\n \"name\": \"Shelf\",\n \"type\": \"control\",\n \"required\": false\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"frequency\",\n \"name\": \"Frequency (Hz)\",\n \"type\": \"number\",\n \"default\": 1000,\n \"min\": 20,\n \"max\": 10000,\n \"conversion\": \"LOGFREQ\",\n \"description\": \"The corner frequency of the shelving filter in Hz.\",\n \"step\": 1\n },\n {\n \"id\": \"shelf\",\n \"name\": \"Shelf Depth\",\n \"type\": \"number\",\n \"default\": -6,\n \"min\": -40,\n \"max\": -3,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"hpf_state\",\n \"temp\"\n ]\n}\n---\n; Shelving HPF\nrdax ${input.in}, 1.0\n\n@if pinConnected(shelf_ctrl)\n; Shelf modulated by control input\n@comment \"Dynamic shelf control\"\nwrax ${reg.temp}, -(1.0 - ${shelf})\nrdfx ${reg.hpf_state}, ${frequency}\nwrlx ${reg.hpf_state}, -1.0\nmulx ${input.shelf_ctrl}\nrdax ${reg.temp}, 1.0\n@else\n; Fixed shelf depth\nrdfx ${reg.hpf_state}, ${frequency}\nwrhx ${reg.hpf_state}, -(1.0 - ${shelf})\n@endif\n\nwrax ${output.out}, 0.0\n"
|
|
3297
3297
|
},
|
|
3298
3298
|
{
|
|
3299
3299
|
"type": "filter.shelving_lpf",
|
|
@@ -3350,8 +3350,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3350
3350
|
"lpf_state",
|
|
3351
3351
|
"temp"
|
|
3352
3352
|
],
|
|
3353
|
-
"template": "; Shelving LPF\
|
|
3354
|
-
"_rawAtl": "---\
|
|
3353
|
+
"template": "; Shelving LPF\nrdax ${input.in}, 1.0\n\n@if pinConnected(shelf_ctrl)\n; Shelf modulated by control input\n@comment \"Dynamic shelf control\"\nwrax ${reg.temp}, -(1.0 - ${shelf})\nrdfx ${reg.lpf_state}, ${frequency}\nwrhx ${reg.lpf_state}, -1.0\nmulx ${input.shelf_ctrl}\nrdax ${reg.temp}, 1.0\n@else\n; Fixed shelf depth\nrdfx ${reg.lpf_state}, ${frequency}\nwrlx ${reg.lpf_state}, -(1.0 - ${shelf})\n@endif\n\nwrax ${output.out}, 0.0",
|
|
3354
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.shelving_lpf\",\n \"name\": \"Shelving LPF\",\n \"category\": \"Filter\",\n \"description\": \"Low-pass filter with adjustable shelf depth\",\n \"color\": \"#24f26f\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"shelf_ctrl\",\n \"name\": \"Shelf\",\n \"type\": \"control\",\n \"required\": false\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"frequency\",\n \"name\": \"Frequency (Hz)\",\n \"type\": \"number\",\n \"default\": 1000,\n \"min\": 20,\n \"max\": 10000,\n \"conversion\": \"LOGFREQ\",\n \"description\": \"The corner frequency of the shelving filter in Hz.\",\n \"step\": 1\n },\n {\n \"id\": \"shelf\",\n \"name\": \"Shelf Depth\",\n \"type\": \"number\",\n \"default\": -6,\n \"min\": -40,\n \"max\": -3,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"lpf_state\",\n \"temp\"\n ]\n}\n---\n; Shelving LPF\nrdax ${input.in}, 1.0\n\n@if pinConnected(shelf_ctrl)\n; Shelf modulated by control input\n@comment \"Dynamic shelf control\"\nwrax ${reg.temp}, -(1.0 - ${shelf})\nrdfx ${reg.lpf_state}, ${frequency}\nwrhx ${reg.lpf_state}, -1.0\nmulx ${input.shelf_ctrl}\nrdax ${reg.temp}, 1.0\n@else\n; Fixed shelf depth\nrdfx ${reg.lpf_state}, ${frequency}\nwrlx ${reg.lpf_state}, -(1.0 - ${shelf})\n@endif\n\nwrax ${output.out}, 0.0\n"
|
|
3355
3355
|
},
|
|
3356
3356
|
{
|
|
3357
3357
|
"type": "filter.svf_2p",
|
|
@@ -3424,8 +3424,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3424
3424
|
"lp_state",
|
|
3425
3425
|
"bp_state"
|
|
3426
3426
|
],
|
|
3427
|
-
"template": "@section header\
|
|
3428
|
-
"_rawAtl": "---\
|
|
3427
|
+
"template": "@section header\n ; Resonance bounds: Calculate Damping (d = 1/Q)\n equ d_target (${param.q})\n\n@section main\n ; --- 2-Pole SVF (Standard Hal Chamberlin Topology) ---\n\n ; 1. Calculate High Pass (H = I - L_old - d * B_old)\n ; Fixed Damping (saves register usage & CPU cycles)\n rdax ${input.in}, 1.0 ; ACC = I\n rdax ${reg.lp_state}, -1.0 ; ACC = I - L_old\n rdax ${reg.bp_state}, -(d_target) ; ACC = I - L_old - d_fixed * B_old = HighPass\n\n @if pinConnected(hp)\n wrax ${output.hp}, 1.0 ; EXPORT High Pass (ACC remains H)\n @endif\n\n @if pinConnected(notch)\n ; Perfect Chamberlin Notch: H + L_old\n rdax ${reg.lp_state}, 1.0 ; ACC = H + L_old\n wrax ${output.notch}, -1.0 ; EXPORT Notch, ACC = - (H + L_old)\n rdax ${reg.lp_state}, 1.0 ; ACC = -H - L_old + L_old = -H\n sof -1.0, 0.0 ; ACC = H (Restoring H for next integration step)\n @endif\n\n ; 2. Calculate Band Pass update (B_new = B_old + F * H)\n ; High Pass is currently in ACC\n @mulcv f_cv ; ACC = F * H\n rdax ${reg.bp_state}, 1.0 ; ACC = F * H + B_old = B_new\n @if pinConnected(bp)\n wrax ${output.bp}, 1.0 ; EXPORT Band Pass\n @endif\n wrax ${reg.bp_state}, 1.0 ; REG_B = B_new, ACC = B_new\n\n ; 3. Calculate Low Pass update (L_new = L_old + F * B_new)\n ; Band Pass is currently in ACC\n @mulcv f_cv ; ACC = F * B_new\n rdax ${reg.lp_state}, 1.0 ; ACC = F * B_new + L_old = L_new\n @if pinConnected(lp)\n wrax ${output.lp}, 1.0 ; EXPORT Low Pass\n @endif\n wrax ${reg.lp_state}, 0.0 ; REG_L = L_new, ACC = 0",
|
|
3428
|
+
"_rawAtl": "---\n{\n \"type\": \"filter.svf_2p\",\n \"name\": \"2-Pole SVF\",\n \"category\": \"Filter\",\n \"description\": \"2-pole State Variable Filter\",\n \"color\": \"#24f26f\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"f_cv\",\n \"name\": \"Freq CV\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"frequency\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"lp\",\n \"name\": \"Low Pass\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"bp\",\n \"name\": \"Band Pass\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"hp\",\n \"name\": \"High Pass\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"notch\",\n \"name\": \"Notch\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"frequency\",\n \"name\": \"Frequency (Hz)\",\n \"type\": \"number\",\n \"min\": 20,\n \"max\": 10000,\n \"default\": 1000,\n \"conversion\": \"SVFFREQ\",\n \"description\": \"Center or cutoff frequency.\"\n },\n {\n \"id\": \"q\",\n \"name\": \"Resonance (Q)\",\n \"type\": \"number\",\n \"min\": 0.5,\n \"max\": 100.0,\n \"step\": 0.001,\n \"default\": 0.707,\n \"conversion\": \"SVF_DAMP\",\n \"description\": \"The maximum resonance filter peak.\"\n }\n ],\n \"registers\": [\n \"lp_state\",\n \"bp_state\"\n ]\n}\n---\n@section header\n ; Resonance bounds: Calculate Damping (d = 1/Q)\n equ d_target (${param.q})\n\n@section main\n ; --- 2-Pole SVF (Standard Hal Chamberlin Topology) ---\n\n ; 1. Calculate High Pass (H = I - L_old - d * B_old)\n ; Fixed Damping (saves register usage & CPU cycles)\n rdax ${input.in}, 1.0 ; ACC = I\n rdax ${reg.lp_state}, -1.0 ; ACC = I - L_old\n rdax ${reg.bp_state}, -(d_target) ; ACC = I - L_old - d_fixed * B_old = HighPass\n\n @if pinConnected(hp)\n wrax ${output.hp}, 1.0 ; EXPORT High Pass (ACC remains H)\n @endif\n\n @if pinConnected(notch)\n ; Perfect Chamberlin Notch: H + L_old\n rdax ${reg.lp_state}, 1.0 ; ACC = H + L_old\n wrax ${output.notch}, -1.0 ; EXPORT Notch, ACC = - (H + L_old)\n rdax ${reg.lp_state}, 1.0 ; ACC = -H - L_old + L_old = -H\n sof -1.0, 0.0 ; ACC = H (Restoring H for next integration step)\n @endif\n\n ; 2. Calculate Band Pass update (B_new = B_old + F * H)\n ; High Pass is currently in ACC\n @mulcv f_cv ; ACC = F * H\n rdax ${reg.bp_state}, 1.0 ; ACC = F * H + B_old = B_new\n @if pinConnected(bp)\n wrax ${output.bp}, 1.0 ; EXPORT Band Pass\n @endif\n wrax ${reg.bp_state}, 1.0 ; REG_B = B_new, ACC = B_new\n\n ; 3. Calculate Low Pass update (L_new = L_old + F * B_new)\n ; Band Pass is currently in ACC\n @mulcv f_cv ; ACC = F * B_new\n rdax ${reg.lp_state}, 1.0 ; ACC = F * B_new + L_old = L_new\n @if pinConnected(lp)\n wrax ${output.lp}, 1.0 ; EXPORT Low Pass\n @endif\n wrax ${reg.lp_state}, 0.0 ; REG_L = L_new, ACC = 0\n"
|
|
3429
3429
|
},
|
|
3430
3430
|
{
|
|
3431
3431
|
"type": "fx.chorus",
|
|
@@ -3520,8 +3520,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3520
3520
|
}
|
|
3521
3521
|
],
|
|
3522
3522
|
"registers": [],
|
|
3523
|
-
"template": "@if isequalto lfoSel 0\
|
|
3524
|
-
"_rawAtl": "---\
|
|
3523
|
+
"template": "@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Initialize LFO\nskp run, done_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_lfo:\n\n@section main\n@multiplyDouble lfo_depth_delay width 0.5\n@multiplyDouble delay_mem_size baseDelay 2.0\n@assert lfo_depth_delay < delay_mem_size, \"Maximum LFO depth exceeds delay memory bounds. Increase base delay or decrease LFO depth.\"\n\n; Chorus\nrdax ${input.in}, 1.0\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(lfo_rate)\nrdax ${input.lfo_rate}, ${param.rate.max} / 511.0\nsof 1.0, ${param.rate.min} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n@if pinConnected(lfo_width)\nrdax ${input.lfo_width}, ${param.width.max} / 32767.0\nsof 1.0, ${param.width.min} / 32767.0\nwrax ${lfoRange}, 0.0\n@endif\n\n; Read modulated tap (wet signal)\n; center offset from start of delay line\n@equals center ${mem.delayl} + ${baseDelay}\ncho rda, ${lfoNum}, SIN | REG | COMPC, ${center}\ncho rda, ${lfoNum}, SIN, ${center} + 1\n\nwrax ${output.out}, 0.0",
|
|
3524
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.chorus\",\n \"name\": \"Chorus\",\n \"category\": \"Effects\",\n \"subcategory\": \"Modulation\",\n \"description\": \"Classic chorus with LFO-modulated delay\",\n \"color\": \"#24f2f2\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"lfo_rate\",\n \"name\": \"LFO Rate\",\n \"type\": \"control\",\n \"required\": false\n },\n {\n \"id\": \"lfo_width\",\n \"name\": \"LFO Width\",\n \"type\": \"control\",\n \"required\": false\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"baseDelay\",\n \"name\": \"Base Delay (ms)\",\n \"type\": \"number\",\n \"default\": 15,\n \"min\": 1,\n \"max\": 50,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"Base delay time (center of modulation) in ms.\",\n \"step\": 0.1\n },\n {\n \"id\": \"rate\",\n \"name\": \"LFO Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.05,\n \"max\": 10,\n \"conversion\": \"HZ_TO_LFO_RATE\",\n \"description\": \"Frequency of the chorus modulation in Hz.\",\n \"step\": 0.01\n },\n {\n \"id\": \"width\",\n \"name\": \"LFO Width (ms)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 10,\n \"conversion\": \"MS_TO_LFO_RANGE\",\n \"description\": \"The width of modulation in ms.\",\n \"step\": 0.1\n },\n {\n \"id\": \"lfoSel\",\n \"name\": \"LFO Select\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n {\n \"value\": 0,\n \"label\": \"LFO 0\"\n },\n {\n \"value\": 1,\n \"label\": \"LFO 1\"\n }\n ]\n }\n ],\n \"memories\": [\n {\n \"id\": \"delayl\",\n \"size\": \"${baseDelay} * 2\"\n }\n ],\n \"registers\": [\n ]\n}\n---\n@if isequalto lfoSel 0\n@equals lfoNum SIN0\n@equals lfoRateReg SIN0_RATE\n@equals lfoRange SIN0_RANGE\n@else\n@equals lfoNum SIN1\n@equals lfoRateReg SIN1_RATE\n@equals lfoRange SIN1_RANGE\n@endif\n\n@section init\n; Initialize LFO\nskp run, done_lfo\nwlds ${lfoNum}, ${rate}, ${width}\ndone_lfo:\n\n@section main\n@multiplyDouble lfo_depth_delay width 0.5\n@multiplyDouble delay_mem_size baseDelay 2.0\n@assert lfo_depth_delay < delay_mem_size, \"Maximum LFO depth exceeds delay memory bounds. Increase base delay or decrease LFO depth.\"\n\n; Chorus\nrdax ${input.in}, 1.0\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(lfo_rate)\nrdax ${input.lfo_rate}, ${param.rate.max} / 511.0\nsof 1.0, ${param.rate.min} / 511.0\nwrax ${lfoRateReg}, 0.0\n@endif\n\n@if pinConnected(lfo_width)\nrdax ${input.lfo_width}, ${param.width.max} / 32767.0\nsof 1.0, ${param.width.min} / 32767.0\nwrax ${lfoRange}, 0.0\n@endif\n\n; Read modulated tap (wet signal)\n; center offset from start of delay line\n@equals center ${mem.delayl} + ${baseDelay}\ncho rda, ${lfoNum}, SIN | REG | COMPC, ${center}\ncho rda, ${lfoNum}, SIN, ${center} + 1\n\nwrax ${output.out}, 0.0\n"
|
|
3525
3525
|
},
|
|
3526
3526
|
{
|
|
3527
3527
|
"type": "fx.delay.tripletap",
|
|
@@ -3659,8 +3659,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3659
3659
|
"registers": [
|
|
3660
3660
|
"temp"
|
|
3661
3661
|
],
|
|
3662
|
-
"template": "; ThreeTap Delay\
|
|
3663
|
-
"_rawAtl": "---\
|
|
3662
|
+
"template": "; ThreeTap Delay\n@if pinConnected(feedback)\nrdax ${input.feedback}, 1.0 ; Read at unity — @cv fbk_ctrl applies the gain scaling below\nwrax ${reg.temp}, 0.0\n@cv fbk_ctrl ; ACC = fbkGain_linear * pot (or just fbkGain_linear if unconnected)\nmulx ${reg.temp} ; ACC = feedback * fbkGain [* pot]\n@endif\nrdax ${input.in}, ${inputGain}\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(tap1)\n; Tap 1\n@cv delay_time_1\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap1}, 0.0\n@endif\n\n@if pinConnected(tap2)\n; Tap 2\n@cv delay_time_2\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap2}, 0.0\n@endif\n\n@if pinConnected(tap3)\n; Tap 3\n@cv delay_time_3\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap3}, 0.0\n@endif",
|
|
3663
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.delay.tripletap\",\n \"name\": \"ThreeTap\",\n \"category\": \"Effects\",\n \"subcategory\": \"Delay\",\n \"description\": \"Triple tap delay with independent outputs and CV modulation\",\n \"color\": \"#6060c4\",\n \"width\": 200,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"feedback\",\n \"name\": \"Feedback\",\n \"type\": \"audio\",\n \"required\": false\n },\n {\n \"id\": \"delay_time_1\",\n \"name\": \"Delay Time 1\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"tap1Time\"\n },\n {\n \"id\": \"delay_time_2\",\n \"name\": \"Delay Time 2\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"tap2Time\"\n },\n {\n \"id\": \"delay_time_3\",\n \"name\": \"Delay Time 3\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"tap3Time\"\n },\n {\n \"id\": \"fbk_ctrl\",\n \"name\": \"Feedback Gain\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"fbkGain\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"tap1\",\n \"name\": \"Tap 1 Out\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"tap2\",\n \"name\": \"Tap 2 Out\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"tap3\",\n \"name\": \"Tap 3 Out\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"inputGain\",\n \"name\": \"Input Gain (dB)\",\n \"type\": \"number\",\n \"default\": 0,\n \"min\": -24,\n \"max\": 0,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n },\n {\n \"id\": \"fbkGain\",\n \"name\": \"Feedback Gain (dB)\",\n \"type\": \"number\",\n \"default\": -6,\n \"min\": -24,\n \"max\": 0,\n \"conversion\": \"DBLEVEL\",\n \"step\": 0.01\n },\n {\n \"id\": \"delayTime\",\n \"name\": \"Total Delay (ms)\",\n \"type\": \"number\",\n \"default\": 1000,\n \"min\": 10,\n \"max\": 1000,\n \"conversion\": \"MS_TO_SAMPLES\",\n \"description\": \"The total delay memory allocated in ms.\",\n \"step\": 1\n },\n {\n \"id\": \"tap1Time\",\n \"name\": \"Tap 1 Time\",\n \"type\": \"number\",\n \"default\": 0.85,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n },\n {\n \"id\": \"tap2Time\",\n \"name\": \"Tap 2 Time\",\n \"type\": \"number\",\n \"default\": 0.60,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n },\n {\n \"id\": \"tap3Time\",\n \"name\": \"Tap 3 Time\",\n \"type\": \"number\",\n \"default\": 0.45,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n }\n ],\n \"memories\": [\n {\n \"id\": \"delayl\",\n \"size\": \"delayTime\"\n }\n ],\n \"registers\": [\n \"temp\"\n ]\n}\n---\n; ThreeTap Delay\n@if pinConnected(feedback)\nrdax ${input.feedback}, 1.0 ; Read at unity — @cv fbk_ctrl applies the gain scaling below\nwrax ${reg.temp}, 0.0\n@cv fbk_ctrl ; ACC = fbkGain_linear * pot (or just fbkGain_linear if unconnected)\nmulx ${reg.temp} ; ACC = feedback * fbkGain [* pot]\n@endif\nrdax ${input.in}, ${inputGain}\nwra ${mem.delayl}, 0.0\n\n@if pinConnected(tap1)\n; Tap 1\n@cv delay_time_1\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap1}, 0.0\n@endif\n\n@if pinConnected(tap2)\n; Tap 2\n@cv delay_time_2\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap2}, 0.0\n@endif\n\n@if pinConnected(tap3)\n; Tap 3\n@cv delay_time_3\nsof (${delayTime} / ${Fs}), ((${mem.delayl} + 1.0) / ${Fs})\nwrax ADDR_PTR, 0.0\nrmpa 1.0\nwrax ${output.tap3}, 0.0\n@endif\n\n"
|
|
3664
3664
|
},
|
|
3665
3665
|
{
|
|
3666
3666
|
"type": "fx.ducking_reverb",
|
|
@@ -3754,8 +3754,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3754
3754
|
"duck_sens_val",
|
|
3755
3755
|
"decay_val"
|
|
3756
3756
|
],
|
|
3757
|
-
"template": "@section main\
|
|
3758
|
-
"_rawAtl": "---\
|
|
3757
|
+
"template": "@section main\n @equals kap 0.5\n \n ; Evaluate CVs\n @cv duck_sens_cv\n wrax ${reg.duck_sens_val}, 0.0\n @cv decay_cv\n wrax ${reg.decay_val}, 0.0\n \n ; 1. Envelope Follower (Fast Attack, Slow Release)\n rdax ${input.in}, 1.0\n absa\n rdax ${reg.env}, -1.0 ; ACC = |IN| - ENV\n skp gez, attack\n ; Release path\n sof 0.005, 0.0 ; Slow release\n skp run, update_env\nattack:\n sof 0.5, 0.0 ; Fast attack\nupdate_env:\n rdax ${reg.env}, 1.0 ; ACC = Delta + ENV\n wrax ${reg.env}, 1.0 ; Update ENV register, keeping ENV in ACC\n \n ; 2. Calculate Ducking Gain (Gain = 1.0 - Sens * ENV)\n ; Limit Gain from dropping below 0\n rdax ${reg.env}, -0.25 ; ACC = -ENV/4 (Scale down env impact to allow high sens numbers)\n mulx ${reg.duck_sens_val} ; ACC = -ENV/4 * Sens\n sof 1.0, 1.0 ; ACC = 1.0 - (ENV/4 * Sens)\n \n ; Clamp Gain to positive values\n skp gez, no_clamp\n sof 0.0, 0.0\nno_clamp:\n wrax ${reg.gain}, 0.0 ; Save final Ducking Gain\n \n ; 3. Reverb Input scaling (Wet signal only)\n rdax ${input.in}, 0.25\n mulx ${reg.gain} ; ACC = Input * DuckingGain\n\n ; 4. Reverb Processing (Minimal 4 Allpass, 2 Delay Network)\n rda ${mem.ap1}#, ${kap}\n wrap ${mem.ap1}, -1.0\n rda ${mem.ap2}#, ${kap}\n wrap ${mem.ap2}, -1.0\n rda ${mem.ap3}#, ${kap}\n wrap ${mem.ap3}, -1.0\n rda ${mem.ap4}#, ${kap}\n wrap ${mem.ap4}, -1.0\n \n ; Saving Allpass Output to write into the reverb tank\n wrax ${reg.apout}, 0.0\n \n ; Delay Loop 1 (Tank Left)\n rdax ${reg.apout}, 1.0\n rda ${mem.del2}#, 1.0\n mulx ${reg.decay_val}\n wra ${mem.del1}, 0.0\n\n ; Delay Loop 2 (Tank Right)\n rdax ${reg.apout}, 1.0\n rda ${mem.del1}#, 1.0\n mulx ${reg.decay_val}\n wra ${mem.del2}, 0.0\n \n ; 5. Output\n rda ${mem.del1}#, 1.0\n rda ${mem.del2}#, 1.0\n wrax ${output.out}, 0.0",
|
|
3758
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.ducking_reverb\",\n \"name\": \"Ducking Reverb\",\n \"category\": \"Effects\",\n \"subcategory\": \"Reverb\",\n \"description\": \"Reverb that automatically ducks in volume while you are playing.\",\n \"color\": \"#7100fc\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Audio Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"decay_cv\",\n \"name\": \"Decay\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"decay\"\n },\n {\n \"id\": \"duck_sens_cv\",\n \"name\": \"Sensitivity\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"duck_sens\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Audio Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"decay\",\n \"name\": \"Reverb Decay\",\n \"type\": \"number\",\n \"default\": 0.85,\n \"min\": 0,\n \"max\": 0.99,\n \"step\": 0.01,\n \"description\": \"Length of the reverb tail.\"\n },\n {\n \"id\": \"duck_sens\",\n \"name\": \"Ducking Sensitivity\",\n \"type\": \"number\",\n \"default\": 2.0,\n \"min\": 0.0,\n \"max\": 10.0,\n \"step\": 0.1,\n \"description\": \"How hard the reverb ducks when you play.\"\n }\n ],\n \"memories\": [\n { \"id\": \"ap1\", \"size\": 142 },\n { \"id\": \"ap2\", \"size\": 379 },\n { \"id\": \"ap3\", \"size\": 842 },\n { \"id\": \"ap4\", \"size\": 1111 },\n { \"id\": \"del1\", \"size\": 4012 },\n { \"id\": \"del2\", \"size\": 5211 }\n ],\n \"registers\": [\n \"env\",\n \"gain\",\n \"apout\",\n \"duck_sens_val\",\n \"decay_val\"\n ]\n}\n---\n@section main\n @equals kap 0.5\n \n ; Evaluate CVs\n @cv duck_sens_cv\n wrax ${reg.duck_sens_val}, 0.0\n @cv decay_cv\n wrax ${reg.decay_val}, 0.0\n \n ; 1. Envelope Follower (Fast Attack, Slow Release)\n rdax ${input.in}, 1.0\n absa\n rdax ${reg.env}, -1.0 ; ACC = |IN| - ENV\n skp gez, attack\n ; Release path\n sof 0.005, 0.0 ; Slow release\n skp run, update_env\nattack:\n sof 0.5, 0.0 ; Fast attack\nupdate_env:\n rdax ${reg.env}, 1.0 ; ACC = Delta + ENV\n wrax ${reg.env}, 1.0 ; Update ENV register, keeping ENV in ACC\n \n ; 2. Calculate Ducking Gain (Gain = 1.0 - Sens * ENV)\n ; Limit Gain from dropping below 0\n rdax ${reg.env}, -0.25 ; ACC = -ENV/4 (Scale down env impact to allow high sens numbers)\n mulx ${reg.duck_sens_val} ; ACC = -ENV/4 * Sens\n sof 1.0, 1.0 ; ACC = 1.0 - (ENV/4 * Sens)\n \n ; Clamp Gain to positive values\n skp gez, no_clamp\n sof 0.0, 0.0\nno_clamp:\n wrax ${reg.gain}, 0.0 ; Save final Ducking Gain\n \n ; 3. Reverb Input scaling (Wet signal only)\n rdax ${input.in}, 0.25\n mulx ${reg.gain} ; ACC = Input * DuckingGain\n\n ; 4. Reverb Processing (Minimal 4 Allpass, 2 Delay Network)\n rda ${mem.ap1}#, ${kap}\n wrap ${mem.ap1}, -1.0\n rda ${mem.ap2}#, ${kap}\n wrap ${mem.ap2}, -1.0\n rda ${mem.ap3}#, ${kap}\n wrap ${mem.ap3}, -1.0\n rda ${mem.ap4}#, ${kap}\n wrap ${mem.ap4}, -1.0\n \n ; Saving Allpass Output to write into the reverb tank\n wrax ${reg.apout}, 0.0\n \n ; Delay Loop 1 (Tank Left)\n rdax ${reg.apout}, 1.0\n rda ${mem.del2}#, 1.0\n mulx ${reg.decay_val}\n wra ${mem.del1}, 0.0\n\n ; Delay Loop 2 (Tank Right)\n rdax ${reg.apout}, 1.0\n rda ${mem.del1}#, 1.0\n mulx ${reg.decay_val}\n wra ${mem.del2}, 0.0\n \n ; 5. Output\n rda ${mem.del1}#, 1.0\n rda ${mem.del2}#, 1.0\n wrax ${output.out}, 0.0\n"
|
|
3759
3759
|
},
|
|
3760
3760
|
{
|
|
3761
3761
|
"type": "fx.harmonic_tremolo",
|
|
@@ -3833,8 +3833,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3833
3833
|
"lfo_inv",
|
|
3834
3834
|
"depth_temp"
|
|
3835
3835
|
],
|
|
3836
|
-
"template": "@section init\
|
|
3837
|
-
"_rawAtl": "---\
|
|
3836
|
+
"template": "@section init\n skp run, init_trem\n ; Depth in WLDS is useless for RDAL (RDAL reads raw sine), so max it\n wlds SIN0, ${rate}, 32767\n init_trem:\n\n@section main\n ; 0. Evaluate Rate CV dynamically (Scaled manually to avoid SOF > 1.99 limits from HZ_TO_LFO_RATE bounds)\n @if pinConnected(rate_cv)\n rdax ${input.rate_cv}, ${rate} / 511.0\n wrax SIN0_RATE, 0.0\n @endif\n\n ; 1. Evaluate Depth CV dynamically\n @cv depth_cv ; ACC = Depth (0.0 to 1.0)\n sof 0.5, 0.0 ; ACC = Depth / 2\n wrax ${reg.depth_temp}, 0.0 ; Save scaled depth\n\n ; 2. Generate LFO\n cho rdal, SIN0 ; ACC = LFO (-1.0 to 1.0)\n mulx ${reg.depth_temp} ; ACC = LFO * (Depth / 2)\n sof 1.0, 0.5 ; ACC = LFO * (Depth / 2) + 0.5 (Scale to 0.0 - 1.0)\n wrax ${reg.lfo_val}, -1.0 ; Save LFO_VAL, ACC = -LFO_VAL\n sof 1.0, 1.0 ; ACC = 1.0 - LFO_VAL\n wrax ${reg.lfo_inv}, 0.0 ; Save LFO_INV, ACC = 0\n \n ; 2. Crossover Filter (1-Pole)\n ; Lowpass = L_old + F * (Input - L_old)\n rdax ${input.in}, 1.0 ; ACC = Input\n rdax ${reg.lpf_state}, -1.0 ; ACC = Input - L_old\n sof ${param.crossover}, 0.0 ; ACC = F * (Input - L_old)\n rdax ${reg.lpf_state}, 1.0 ; ACC = F * (Input - L_old) + L_old\n wrax ${reg.lpf_state}, -1.0 ; REG_L = Lowpass, ACC = -Lowpass\n \n ; Highpass = Input - Lowpass\n rdax ${input.in}, 1.0 ; ACC = Input - Lowpass = Highpass\n \n ; 3. Modulate Highpass\n mulx ${reg.lfo_inv} ; ACC = Highpass * LFO_INV\n \n ; 4. Modulate Lowpass & Mix\n ; Need to bring Highpass to a free register, but we can just use lfo_inv as a temp\n wrax ${reg.lfo_inv}, 0.0 ; Save modulated Highpass in lfo_inv\n \n rdax ${reg.lpf_state}, 1.0 ; ACC = Lowpass\n mulx ${reg.lfo_val} ; ACC = Lowpass * LFO_VAL\n rdax ${reg.lfo_inv}, 1.0 ; ACC = (Lowpass * LFO) + (Highpass * LFO_INV)\n \n ; 5. Output\n wrax ${output.out}, 0.0",
|
|
3837
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.harmonic_tremolo\",\n \"name\": \"Harmonic Tremolo\",\n \"category\": \"Effects\",\n \"subcategory\": \"Modulation\",\n \"description\": \"True vintage harmonic tremolo using a crossover.\",\n \"color\": \"#24F2F2\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"rate_cv\",\n \"name\": \"Rate\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"rate\"\n },\n {\n \"id\": \"depth_cv\",\n \"name\": \"Depth\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"depth\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"rate\",\n \"name\": \"Tremolo Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 3.0,\n \"min\": 0.5,\n \"max\": 12.0,\n \"step\": 0.1,\n \"conversion\": \"HZ_TO_LFO_RATE\"\n },\n {\n \"id\": \"depth\",\n \"name\": \"Depth\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"Intensity of the tremolo effect.\"\n },\n {\n \"id\": \"crossover\",\n \"name\": \"Crossover Freq\",\n \"type\": \"number\",\n \"default\": 600,\n \"min\": 100,\n \"max\": 2000,\n \"step\": 10,\n \"conversion\": \"SVFFREQ\",\n \"description\": \"Frequency split for the two bands.\"\n }\n ],\n \"registers\": [\n \"lpf_state\",\n \"lfo_val\",\n \"lfo_inv\",\n \"depth_temp\"\n ]\n}\n---\n@section init\n skp run, init_trem\n ; Depth in WLDS is useless for RDAL (RDAL reads raw sine), so max it\n wlds SIN0, ${rate}, 32767\n init_trem:\n\n@section main\n ; 0. Evaluate Rate CV dynamically (Scaled manually to avoid SOF > 1.99 limits from HZ_TO_LFO_RATE bounds)\n @if pinConnected(rate_cv)\n rdax ${input.rate_cv}, ${rate} / 511.0\n wrax SIN0_RATE, 0.0\n @endif\n\n ; 1. Evaluate Depth CV dynamically\n @cv depth_cv ; ACC = Depth (0.0 to 1.0)\n sof 0.5, 0.0 ; ACC = Depth / 2\n wrax ${reg.depth_temp}, 0.0 ; Save scaled depth\n\n ; 2. Generate LFO\n cho rdal, SIN0 ; ACC = LFO (-1.0 to 1.0)\n mulx ${reg.depth_temp} ; ACC = LFO * (Depth / 2)\n sof 1.0, 0.5 ; ACC = LFO * (Depth / 2) + 0.5 (Scale to 0.0 - 1.0)\n wrax ${reg.lfo_val}, -1.0 ; Save LFO_VAL, ACC = -LFO_VAL\n sof 1.0, 1.0 ; ACC = 1.0 - LFO_VAL\n wrax ${reg.lfo_inv}, 0.0 ; Save LFO_INV, ACC = 0\n \n ; 2. Crossover Filter (1-Pole)\n ; Lowpass = L_old + F * (Input - L_old)\n rdax ${input.in}, 1.0 ; ACC = Input\n rdax ${reg.lpf_state}, -1.0 ; ACC = Input - L_old\n sof ${param.crossover}, 0.0 ; ACC = F * (Input - L_old)\n rdax ${reg.lpf_state}, 1.0 ; ACC = F * (Input - L_old) + L_old\n wrax ${reg.lpf_state}, -1.0 ; REG_L = Lowpass, ACC = -Lowpass\n \n ; Highpass = Input - Lowpass\n rdax ${input.in}, 1.0 ; ACC = Input - Lowpass = Highpass\n \n ; 3. Modulate Highpass\n mulx ${reg.lfo_inv} ; ACC = Highpass * LFO_INV\n \n ; 4. Modulate Lowpass & Mix\n ; Need to bring Highpass to a free register, but we can just use lfo_inv as a temp\n wrax ${reg.lfo_inv}, 0.0 ; Save modulated Highpass in lfo_inv\n \n rdax ${reg.lpf_state}, 1.0 ; ACC = Lowpass\n mulx ${reg.lfo_val} ; ACC = Lowpass * LFO_VAL\n rdax ${reg.lfo_inv}, 1.0 ; ACC = (Lowpass * LFO) + (Highpass * LFO_INV)\n \n ; 5. Output\n wrax ${output.out}, 0.0\n"
|
|
3838
3838
|
},
|
|
3839
3839
|
{
|
|
3840
3840
|
"type": "fx.micro_stutter",
|
|
@@ -3893,8 +3893,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3893
3893
|
"size": 16384
|
|
3894
3894
|
}
|
|
3895
3895
|
],
|
|
3896
|
-
"template": "@section main\
|
|
3897
|
-
"_rawAtl": "---\
|
|
3896
|
+
"template": "@section main\n ; Check Freeze CV status\n @if pinConnected(freeze_cv)\n rdax ${input.freeze_cv}, 1.0\n sof 1.0, -0.5 ; Offset by 0.5\n skp gez, play_grain ; If CV > 0.5, skip the write instruction and just recycle the buffer!\n @endif\n\n ; Write to buffer (Only executes if NOT frozen)\n rdax ${input.in}, 1.0\n wra ${mem.grain}, 0.0\n \nplay_grain:\n ; Read from buffer at Grain Size offset\n @equals offset ${mem.grain} + ${param.grain_size}\n rda ${offset}, ${param.level}\n wrax ${output.out}, 0.0",
|
|
3897
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.micro_stutter\",\n \"name\": \"Micro-Stutter\",\n \"category\": \"Effects\",\n \"subcategory\": \"Lo-Fi\",\n \"description\": \"Glitchy frozen grain effect. When triggered, stops incoming audio and continuously loops the last active grain buffer.\",\n \"color\": \"#6060c4\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"freeze_cv\",\n \"name\": \"Freeze Trigger\",\n \"type\": \"control\",\n \"required\": false,\n \"description\": \"CV input. When value > 0.5, the buffer freezes.\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"grain_size\",\n \"name\": \"Grain Size (ms)\",\n \"type\": \"number\",\n \"default\": 100,\n \"min\": 10,\n \"max\": 500,\n \"step\": 1,\n \"conversion\": \"MS_TO_SAMPLES\"\n },\n {\n \"id\": \"level\",\n \"name\": \"Wet Level\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.5,\n \"step\": 0.05\n }\n ],\n \"memories\": [\n {\n \"id\": \"grain\",\n \"size\": 16384\n }\n ]\n}\n---\n@section main\n ; Check Freeze CV status\n @if pinConnected(freeze_cv)\n rdax ${input.freeze_cv}, 1.0\n sof 1.0, -0.5 ; Offset by 0.5\n skp gez, play_grain ; If CV > 0.5, skip the write instruction and just recycle the buffer!\n @endif\n\n ; Write to buffer (Only executes if NOT frozen)\n rdax ${input.in}, 1.0\n wra ${mem.grain}, 0.0\n \nplay_grain:\n ; Read from buffer at Grain Size offset\n @equals offset ${mem.grain} + ${param.grain_size}\n rda ${offset}, ${param.level}\n wrax ${output.out}, 0.0\n"
|
|
3898
3898
|
},
|
|
3899
3899
|
{
|
|
3900
3900
|
"type": "fx.sub_octave",
|
|
@@ -3955,8 +3955,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
3955
3955
|
"lps",
|
|
3956
3956
|
"lp2"
|
|
3957
3957
|
],
|
|
3958
|
-
"template": "@section init\
|
|
3959
|
-
"_rawAtl": "---\
|
|
3958
|
+
"template": "@section init\n ; Initialize Ramp LFO for EXACTLY -1 Octave (rate -8192 = 0.5x speed)\n skp run, init_sub\n wldr RMP0, -8192, 4096\n init_sub:\n\n@section main\n ; Write input to delay buffer\n rdax ${input.in}, 1.0\n wra ${mem.buffer}, 0.0\n\n ; Read Pitch -1 Octave\n cho rda, RMP0, REG | COMPC, ${mem.buffer}\n cho rda, RMP0, 0, ${mem.buffer} + 1\n wra ${mem.temp}, 0.0\n cho rda, RMP0, RPTR2 | COMPC, ${mem.buffer}\n cho rda, RMP0, RPTR2, ${mem.buffer} + 1\n cho sof, RMP0, NA | COMPC, 0.0\n cho rda, RMP0, NA, ${mem.temp}\n \n ; ACC now contains the raw -1 octave signal\n ; Apply 2-Pole Lowpass filter to clean it up into a synth sine wave\n \n ; Pole 1\n rdax ${reg.lps}, -1.0\n sof ${param.filter_freq}, 0.0\n rdax ${reg.lps}, 1.0\n wrax ${reg.lps}, 1.0\n \n ; Pole 2\n rdax ${reg.lp2}, -1.0\n sof ${param.filter_freq}, 0.0\n rdax ${reg.lp2}, 1.0\n wrax ${reg.lp2}, 1.0\n \n ; Gain\n sof ${param.sub_level}, 0.0\n wrax ${output.out}, 0.0",
|
|
3959
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.sub_octave\",\n \"name\": \"Sub-Octave Synth\",\n \"category\": \"Effects\",\n \"subcategory\": \"Pitch\",\n \"description\": \"Clean -1 octave generator with an integrated lowpass filter to remove pitch-shifting artifacts.\",\n \"color\": \"#fcba03\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"sub_level\",\n \"name\": \"Sub Level\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.5,\n \"step\": 0.05\n },\n {\n \"id\": \"filter_freq\",\n \"name\": \"Filter Frequency\",\n \"type\": \"number\",\n \"default\": 250,\n \"min\": 80,\n \"max\": 800,\n \"step\": 10,\n \"conversion\": \"SVFFREQ\",\n \"description\": \"Frequency cutoff to remove digital fuzz from the pitch shifted signal.\"\n }\n ],\n \"memories\": [\n {\n \"id\": \"buffer\",\n \"size\": 4096\n },\n {\n \"id\": \"temp\",\n \"size\": 1\n }\n ],\n \"registers\": [\n \"lps\",\n \"lp2\"\n ]\n}\n---\n@section init\n ; Initialize Ramp LFO for EXACTLY -1 Octave (rate -8192 = 0.5x speed)\n skp run, init_sub\n wldr RMP0, -8192, 4096\n init_sub:\n\n@section main\n ; Write input to delay buffer\n rdax ${input.in}, 1.0\n wra ${mem.buffer}, 0.0\n\n ; Read Pitch -1 Octave\n cho rda, RMP0, REG | COMPC, ${mem.buffer}\n cho rda, RMP0, 0, ${mem.buffer} + 1\n wra ${mem.temp}, 0.0\n cho rda, RMP0, RPTR2 | COMPC, ${mem.buffer}\n cho rda, RMP0, RPTR2, ${mem.buffer} + 1\n cho sof, RMP0, NA | COMPC, 0.0\n cho rda, RMP0, NA, ${mem.temp}\n \n ; ACC now contains the raw -1 octave signal\n ; Apply 2-Pole Lowpass filter to clean it up into a synth sine wave\n \n ; Pole 1\n rdax ${reg.lps}, -1.0\n sof ${param.filter_freq}, 0.0\n rdax ${reg.lps}, 1.0\n wrax ${reg.lps}, 1.0\n \n ; Pole 2\n rdax ${reg.lp2}, -1.0\n sof ${param.filter_freq}, 0.0\n rdax ${reg.lp2}, 1.0\n wrax ${reg.lp2}, 1.0\n \n ; Gain\n sof ${param.sub_level}, 0.0\n wrax ${output.out}, 0.0\n"
|
|
3960
3960
|
},
|
|
3961
3961
|
{
|
|
3962
3962
|
"type": "fx.tape_degrade",
|
|
@@ -4071,8 +4071,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4071
4071
|
"wow_temp",
|
|
4072
4072
|
"lpf_lp"
|
|
4073
4073
|
],
|
|
4074
|
-
"template": "@section init\
|
|
4075
|
-
"_rawAtl": "---\
|
|
4074
|
+
"template": "@section init\n skp run, init_tape\n wlds SIN0, ${wow_rate}, ${wow_depth}\n wlds SIN1, ${flutter_rate}, ${flutter_depth}\n init_tape:\n\n@section main\n ; CV Modulation for Wow/Flutter \n ; Since rates are HZ_TO_LFO_RATE, we must scale them manually\n @if pinConnected(wow_rate_cv)\n rdax ${input.wow_rate_cv}, ${wow_rate} / 511.0\n wrax SIN0_RATE, 0.0\n @endif\n \n ; Depths are MS_TO_LFO_RANGE which goes up to 32767. So scale / 32767.0\n @if pinConnected(wow_depth_cv)\n rdax ${input.wow_depth_cv}, ${wow_depth} / 32767.0\n wrax SIN0_RANGE, 0.0\n @endif\n\n @if pinConnected(flutter_rate_cv)\n rdax ${input.flutter_rate_cv}, ${flutter_rate} / 511.0\n wrax SIN1_RATE, 0.0\n @endif\n \n @if pinConnected(flutter_depth_cv)\n rdax ${input.flutter_depth_cv}, ${flutter_depth} / 32767.0\n wrax SIN1_RANGE, 0.0\n @endif\n\n ; Write to Tape\n rdax ${input.in}, 1.0\n wra ${mem.tape_buffer}, 0.0\n\n ; Read Wow Tape Head (SIN0)\n @equals center ${mem.tape_buffer} + 2048\n cho rda, SIN0, SIN | REG | COMPC, ${center}\n cho rda, SIN0, SIN, ${center} + 1\n \n ; Modulate with Flutter (SIN1) off the same base, summing them creates composite warble\n ; Actually, FV-1 CHO adds to ACC! So we just do another CHO RDA but without REG tracking?\n ; To maintain unity volume, we shouldn't add audio signals, we should add address offsets.\n ; But we can't add address offsets in SpinASM dynamically easily. \n ; Instead, we just read from the buffer with Flutter and average the two reads!\n ; Multiply Wow read by 0.5\n sof 0.5, 0.0\n wrax ${reg.wow_temp}, 0.0 ; Hold Wow audio separately from LPF state\n\n ; Read Flutter Tape Head (SIN1)\n cho rda, SIN1, SIN | REG | COMPC, ${center}\n cho rda, SIN1, SIN, ${center} + 1\n sof 0.5, 0.0\n\n ; Combine Wow and Flutter audio signals\n rdax ${reg.wow_temp}, 1.0\n\n ; Tape Age Degradation (1-Pole Lowpass: L_new = L_old + Age * (I - L_old))\n ; ACC = composite warble (wow*0.5 + flutter*0.5)\n rdax ${reg.lpf_lp}, -1.0 ; ACC = I - L_old\n sof ${param.age}, 0.0 ; ACC = Age * (I - L_old)\n rdax ${reg.lpf_lp}, 1.0 ; ACC = L_old + Age * (I - L_old) = L_new\n wrax ${reg.lpf_lp}, 1.0 ; Save new state and keep L_new in ACC\n\n ; Export\n wrax ${output.out}, 0.0",
|
|
4075
|
+
"_rawAtl": "---\n{\n \"type\": \"fx.tape_degrade\",\n \"name\": \"Tape Degrader\",\n \"category\": \"Effects\",\n \"subcategory\": \"Lo-Fi\",\n \"description\": \"Simulates tape wow, flutter, and top-end age loss.\",\n \"color\": \"#24F2F2\",\n \"width\": 180,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Input\",\n \"type\": \"audio\",\n \"required\": true\n },\n {\n \"id\": \"wow_rate_cv\",\n \"name\": \"Wow Rate\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"wow_rate\"\n },\n {\n \"id\": \"wow_depth_cv\",\n \"name\": \"Wow Depth\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"wow_depth\"\n },\n {\n \"id\": \"flutter_rate_cv\",\n \"name\": \"Flutter Rate\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"flutter_rate\"\n },\n {\n \"id\": \"flutter_depth_cv\",\n \"name\": \"Flutter Depth\",\n \"type\": \"control\",\n \"required\": false,\n \"parameter\": \"flutter_depth\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"wow_rate\",\n \"name\": \"Wow Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.1,\n \"max\": 2.0,\n \"step\": 0.01,\n \"conversion\": \"HZ_TO_LFO_RATE\"\n },\n {\n \"id\": \"wow_depth\",\n \"name\": \"Wow Depth (ms)\",\n \"type\": \"number\",\n \"default\": 1.5,\n \"min\": 0,\n \"max\": 5.0,\n \"step\": 0.1,\n \"conversion\": \"MS_TO_LFO_RANGE\"\n },\n {\n \"id\": \"flutter_rate\",\n \"name\": \"Flutter Rate (Hz)\",\n \"type\": \"number\",\n \"default\": 12.0,\n \"min\": 5.0,\n \"max\": 20.0,\n \"step\": 0.1,\n \"conversion\": \"HZ_TO_LFO_RATE\"\n },\n {\n \"id\": \"flutter_depth\",\n \"name\": \"Flutter Depth (ms)\",\n \"type\": \"number\",\n \"default\": 0.2,\n \"min\": 0,\n \"max\": 1.5,\n \"step\": 0.01,\n \"conversion\": \"MS_TO_LFO_RANGE\"\n },\n {\n \"id\": \"age\",\n \"name\": \"Tape Age (Tone)\",\n \"type\": \"number\",\n \"default\": 0.3,\n \"min\": 0.01,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"1.0 is bright, lower is darker (aged tape).\"\n }\n ],\n \"memories\": [\n {\n \"id\": \"tape_buffer\",\n \"size\": 4096\n }\n ],\n \"registers\": [\n \"wow_temp\",\n \"lpf_lp\"\n ]\n}\n---\n@section init\n skp run, init_tape\n wlds SIN0, ${wow_rate}, ${wow_depth}\n wlds SIN1, ${flutter_rate}, ${flutter_depth}\n init_tape:\n\n@section main\n ; CV Modulation for Wow/Flutter \n ; Since rates are HZ_TO_LFO_RATE, we must scale them manually\n @if pinConnected(wow_rate_cv)\n rdax ${input.wow_rate_cv}, ${wow_rate} / 511.0\n wrax SIN0_RATE, 0.0\n @endif\n \n ; Depths are MS_TO_LFO_RANGE which goes up to 32767. So scale / 32767.0\n @if pinConnected(wow_depth_cv)\n rdax ${input.wow_depth_cv}, ${wow_depth} / 32767.0\n wrax SIN0_RANGE, 0.0\n @endif\n\n @if pinConnected(flutter_rate_cv)\n rdax ${input.flutter_rate_cv}, ${flutter_rate} / 511.0\n wrax SIN1_RATE, 0.0\n @endif\n \n @if pinConnected(flutter_depth_cv)\n rdax ${input.flutter_depth_cv}, ${flutter_depth} / 32767.0\n wrax SIN1_RANGE, 0.0\n @endif\n\n ; Write to Tape\n rdax ${input.in}, 1.0\n wra ${mem.tape_buffer}, 0.0\n\n ; Read Wow Tape Head (SIN0)\n @equals center ${mem.tape_buffer} + 2048\n cho rda, SIN0, SIN | REG | COMPC, ${center}\n cho rda, SIN0, SIN, ${center} + 1\n \n ; Modulate with Flutter (SIN1) off the same base, summing them creates composite warble\n ; Actually, FV-1 CHO adds to ACC! So we just do another CHO RDA but without REG tracking?\n ; To maintain unity volume, we shouldn't add audio signals, we should add address offsets.\n ; But we can't add address offsets in SpinASM dynamically easily. \n ; Instead, we just read from the buffer with Flutter and average the two reads!\n ; Multiply Wow read by 0.5\n sof 0.5, 0.0\n wrax ${reg.wow_temp}, 0.0 ; Hold Wow audio separately from LPF state\n\n ; Read Flutter Tape Head (SIN1)\n cho rda, SIN1, SIN | REG | COMPC, ${center}\n cho rda, SIN1, SIN, ${center} + 1\n sof 0.5, 0.0\n\n ; Combine Wow and Flutter audio signals\n rdax ${reg.wow_temp}, 1.0\n\n ; Tape Age Degradation (1-Pole Lowpass: L_new = L_old + Age * (I - L_old))\n ; ACC = composite warble (wow*0.5 + flutter*0.5)\n rdax ${reg.lpf_lp}, -1.0 ; ACC = I - L_old\n sof ${param.age}, 0.0 ; ACC = Age * (I - L_old)\n rdax ${reg.lpf_lp}, 1.0 ; ACC = L_old + Age * (I - L_old) = L_new\n wrax ${reg.lpf_lp}, 1.0 ; Save new state and keep L_new in ACC\n\n ; Export\n wrax ${output.out}, 0.0\n"
|
|
4076
4076
|
},
|
|
4077
4077
|
{
|
|
4078
4078
|
"type": "input.adc",
|
|
@@ -4117,8 +4117,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4117
4117
|
"step": 0.01
|
|
4118
4118
|
}
|
|
4119
4119
|
],
|
|
4120
|
-
"template": "@section input\
|
|
4121
|
-
"_rawAtl": "---\
|
|
4120
|
+
"template": "@section input\n@if adcNumber == 0\nrdax ADCL, ${param.gain}\n@else\nrdax ADCR, ${param.gain}\n@endif\nwrax ${output.out}, 0",
|
|
4121
|
+
"_rawAtl": "---\n{\n \"type\": \"input.adc\",\n \"name\": \"ADC Input\",\n \"category\": \"Input/Output\",\n \"description\": \"Reads audio from an analog input (ADC) with adjustable gain.\",\n \"color\": \"#2196F3\",\n \"width\": 150,\n \"labelTemplate\": \"ADC ${param.adcNumber == 0 ? 'L' : 'R'}\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Audio\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"adcNumber\",\n \"name\": \"ADC Number\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n {\n \"label\": \"ADCL\",\n \"value\": 0\n },\n {\n \"label\": \"ADCR\",\n \"value\": 1\n }\n ]\n },\n {\n \"id\": \"gain\",\n \"name\": \"Gain\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 1.9999,\n \"step\": 0.01\n }\n ]\n}\n---\n@section input\n@if adcNumber == 0\nrdax ADCL, ${param.gain}\n@else\nrdax ADCR, ${param.gain}\n@endif\nwrax ${output.out}, 0\n"
|
|
4122
4122
|
},
|
|
4123
4123
|
{
|
|
4124
4124
|
"type": "input.pot",
|
|
@@ -4243,8 +4243,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4243
4243
|
"f1",
|
|
4244
4244
|
"f2"
|
|
4245
4245
|
],
|
|
4246
|
-
"template": "@section input\
|
|
4247
|
-
"_rawAtl": "---\
|
|
4246
|
+
"template": "@section input\n\n@acc = POT${param.potNumber}\n@if ${param.speedup} == true\n ; Speedup filter (lead-lag) for fast response with some smoothing\n RDFX ${reg.f1}, ${param.lpCoeff}\n WRHX ${reg.f1}, ${param.hpCoeff}\n @multiplyDouble negHpCoeff -1.0 ${param.hpCoeff}\n RDAX ${reg.f2}, ${negHpCoeff}\n WRAX ${reg.f2}, 1.0\n@endif\n\n@if ${param.invert} == true\n@acc = @acc * -1.0 + 1.0 ; Invert\n@endif\n\n@if ${param.custom_range} == true\n @if ${param.pot_min} != 0.0 || ${param.pot_max} != 1.0\n @assert ${param.pot_max} > ${param.pot_min}, \"Custom POT scaling: max must be greater than min\"\n @acc = @acc * (${param.pot_max} - ${param.pot_min}) + ${param.pot_min} ; Custom scaling\n @endif\n@endif\n\n${output.out} = @acc",
|
|
4247
|
+
"_rawAtl": "---\n{\n \"type\": \"input.pot\",\n \"name\": \"Potentiometer\",\n \"category\": \"Control\",\n \"description\": \"Reads a hardware potentiometer value with optional filtering (Smoothing or Speedup) and inversion.\",\n \"color\": \"#4CAF50\",\n \"width\": 150,\n \"labelTemplate\": \"POT ${param.potNumber}\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"id\": \"out\",\n \"name\": \"Control\",\n \"type\": \"control\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"potNumber\",\n \"name\": \"Pot Number\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n {\n \"label\": \"POT0\",\n \"value\": 0\n },\n {\n \"label\": \"POT1\",\n \"value\": 1\n },\n {\n \"label\": \"POT2\",\n \"value\": 2\n }\n ]\n },\n {\n \"id\": \"lpCoeff\",\n \"name\": \"LP Coefficient\",\n \"type\": \"number\",\n \"default\": 0.001,\n \"min\": 0.001,\n \"max\": 0.1,\n \"step\": 0.001,\n \"displayDecimals\": 3,\n \"visibleIf\": \"speedup == true\"\n },\n {\n \"id\": \"hpCoeff\",\n \"name\": \"Speedup Amount\",\n \"type\": \"number\",\n \"default\": -0.75,\n \"min\": -0.99,\n \"max\": 0,\n \"step\": 0.01,\n \"visibleIf\": \"speedup == true\",\n \"description\": \"Negative values provide lead (faster response)\"\n },\n {\n \"id\": \"invert\",\n \"name\": \"Invert\",\n \"type\": \"boolean\",\n \"default\": false,\n \"description\": \"Inverts the output value\"\n },\n {\n \"id\": \"speedup\",\n \"name\": \"Speedup\",\n \"type\": \"boolean\",\n \"default\": false,\n \"description\": \"Speeds up the response of the pot\"\n },\n {\n \"id\": \"ignoreIfZero\",\n \"name\": \"Ignore if Zero (Fallback to Default)\",\n \"type\": \"boolean\",\n \"default\": false,\n \"description\": \"If true, blocks connected to this pot will use their default value when the pot is turned down.\"\n },\n {\n \"id\": \"zeroValue\",\n \"name\": \"Zero Bypass Value\",\n \"type\": \"number\",\n \"default\": 0.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"description\": \"The value sent to connected @cv inputs when the pot is turned all the way down (zero-bypass active).\",\n \"visibleIf\": \"ignoreIfZero == true\"\n },\n {\n \"id\": \"custom_range\",\n \"name\": \"Custom Scaling\",\n \"type\": \"boolean\",\n \"default\": false,\n \"description\": \"Custom scaling for the pot\"\n },\n {\n \"id\": \"pot_min\",\n \"name\": \"Min\",\n \"type\": \"number\",\n \"default\": 0.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"visibleIf\": \"custom_range == true\"\n },\n {\n \"id\": \"pot_max\",\n \"name\": \"Max\",\n \"type\": \"number\",\n \"default\": 1.0,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01,\n \"visibleIf\": \"custom_range == true\"\n }\n ],\n \"registers\": [\n \"f1\",\n \"f2\"\n ]\n}\n---\n@section input\n\n@acc = POT${param.potNumber}\n@if ${param.speedup} == true\n ; Speedup filter (lead-lag) for fast response with some smoothing\n RDFX ${reg.f1}, ${param.lpCoeff}\n WRHX ${reg.f1}, ${param.hpCoeff}\n @multiplyDouble negHpCoeff -1.0 ${param.hpCoeff}\n RDAX ${reg.f2}, ${negHpCoeff}\n WRAX ${reg.f2}, 1.0\n@endif\n\n@if ${param.invert} == true\n@acc = @acc * -1.0 + 1.0 ; Invert\n@endif\n\n@if ${param.custom_range} == true\n @if ${param.pot_min} != 0.0 || ${param.pot_max} != 1.0\n @assert ${param.pot_max} > ${param.pot_min}, \"Custom POT scaling: max must be greater than min\"\n @acc = @acc * (${param.pot_max} - ${param.pot_min}) + ${param.pot_min} ; Custom scaling\n @endif\n@endif\n\n${output.out} = @acc"
|
|
4248
4248
|
},
|
|
4249
4249
|
{
|
|
4250
4250
|
"type": "math.crossfade",
|
|
@@ -4305,8 +4305,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4305
4305
|
}
|
|
4306
4306
|
],
|
|
4307
4307
|
"color": "#2468f2",
|
|
4308
|
-
"template": "@section header\
|
|
4309
|
-
"_rawAtl": "---\
|
|
4308
|
+
"template": "@section header\n@comment \"Generated from spincad source file crossfade.spincad\"\n\n@section main\n; Dynamic interpolation or fixed fallback crossfade\n\n@if pinConnected(input0)\n ; Dynamic crossfade using control input (Fade)\n @if pinConnected(input1)\n rdax ${input.input1}, -${gain1}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${gain2}\n @endif\n \n mulx ${input.input0}\n \n @if pinConnected(input1)\n rdax ${input.input1}, ${gain1}\n @endif\n@else\n ; Fallback to static parameter fade\n @if pinConnected(input1)\n rdax ${input.input1}, ((1.0 - ${fade}) * ${gain1})\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, (${fade} * ${gain2})\n @endif\n@endif\n\nwrax ${output.output}, 0.0",
|
|
4309
|
+
"_rawAtl": "---\n{\n \"type\": \"math.crossfade\",\n \"name\": \"Crossfade\",\n \"category\": \"Gain/Mixing\",\n \"description\": \"Crossfades between two audio inputs based on a control signal\",\n \"inputs\": [\n {\n \"id\": \"input1\",\n \"name\": \"Input 1\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input2\",\n \"name\": \"Input 2\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input0\",\n \"name\": \"Fade\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"fade\",\n \"name\": \"Fade\",\n \"type\": \"number\",\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01,\n \"default\": 0.5\n },\n {\n \"id\": \"gain1\",\n \"name\": \"Input 1 Gain\",\n \"type\": \"number\",\n \"min\": -12,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain2\",\n \"name\": \"Input 2 Gain\",\n \"type\": \"number\",\n \"min\": -12,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"color\": \"#2468f2\"\n}\n---\n@section header\n@comment \"Generated from spincad source file crossfade.spincad\"\n\n@section main\n; Dynamic interpolation or fixed fallback crossfade\n\n@if pinConnected(input0)\n ; Dynamic crossfade using control input (Fade)\n @if pinConnected(input1)\n rdax ${input.input1}, -${gain1}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${gain2}\n @endif\n \n mulx ${input.input0}\n \n @if pinConnected(input1)\n rdax ${input.input1}, ${gain1}\n @endif\n@else\n ; Fallback to static parameter fade\n @if pinConnected(input1)\n rdax ${input.input1}, ((1.0 - ${fade}) * ${gain1})\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, (${fade} * ${gain2})\n @endif\n@endif\n\nwrax ${output.output}, 0.0\n"
|
|
4310
4310
|
},
|
|
4311
4311
|
{
|
|
4312
4312
|
"type": "math.crossfade2",
|
|
@@ -4352,8 +4352,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4352
4352
|
"registers": [
|
|
4353
4353
|
"temp"
|
|
4354
4354
|
],
|
|
4355
|
-
"template": "; Crossfade 2\
|
|
4356
|
-
"_rawAtl": "---\
|
|
4355
|
+
"template": "; Crossfade 2\n@section main\n\n@if pinConnected(fade)\n ; Input 2 path\n @if pinConnected(input2)\n clr\n rdax ${input.fade}, -1.0\n sof -2.0, 0.0\n wrax ${reg.temp}, 1.0\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n @endif\n\n ; Input 1 path\n @if pinConnected(input1)\n clr\n rdax ${input.fade}, 1.0\n sof 1.0, -1.0\n sof -2.0, 0.0\n wrax ${reg.temp}, 1.0\n mulx ${input.input1}\n @endif\n\n ; Combined output\n rdax ${reg.temp}, 1.0\n wrax ${output.output}, 0.0\n@else\n ; Fallback to simple crossfade using parameter\n @equals staticFade ${fade}\n @equals staticInvFade (1.0 - ${fade})\n @if pinConnected(input1)\n rdax ${input.input1}, ${staticInvFade}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${staticFade}\n @endif\n wrax ${output.output}, 0.0\n@endif",
|
|
4356
|
+
"_rawAtl": "---\n{\n \"type\": \"math.crossfade2\",\n \"name\": \"Crossfade 2\",\n \"category\": \"Gain/Mixing\",\n \"description\": \"Curbed crossfade between two audio inputs.\",\n \"color\": \"#2468f2\",\n \"inputs\": [\n {\n \"id\": \"input1\",\n \"name\": \"Input 1\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input2\",\n \"name\": \"Input 2\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"fade\",\n \"name\": \"Fade\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"fade\",\n \"name\": \"Fade\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0,\n \"max\": 1,\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"temp\"\n ]\n}\n---\n; Crossfade 2\n@section main\n\n@if pinConnected(fade)\n ; Input 2 path\n @if pinConnected(input2)\n clr\n rdax ${input.fade}, -1.0\n sof -2.0, 0.0\n wrax ${reg.temp}, 1.0\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n @endif\n\n ; Input 1 path\n @if pinConnected(input1)\n clr\n rdax ${input.fade}, 1.0\n sof 1.0, -1.0\n sof -2.0, 0.0\n wrax ${reg.temp}, 1.0\n mulx ${input.input1}\n @endif\n\n ; Combined output\n rdax ${reg.temp}, 1.0\n wrax ${output.output}, 0.0\n@else\n ; Fallback to simple crossfade using parameter\n @equals staticFade ${fade}\n @equals staticInvFade (1.0 - ${fade})\n @if pinConnected(input1)\n rdax ${input.input1}, ${staticInvFade}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${staticFade}\n @endif\n wrax ${output.output}, 0.0\n@endif\n"
|
|
4357
4357
|
},
|
|
4358
4358
|
{
|
|
4359
4359
|
"type": "math.crossfade3",
|
|
@@ -4402,8 +4402,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4402
4402
|
"registers": [
|
|
4403
4403
|
"temp"
|
|
4404
4404
|
],
|
|
4405
|
-
"template": "; Crossfade 3 (Restored Java logic)\
|
|
4406
|
-
"_rawAtl": "---\
|
|
4405
|
+
"template": "; Crossfade 3 (Restored Java logic)\n@section main\n\n@if pinConnected(fade)\n @if pinConnected(input1) && pinConnected(input2)\n rdax ${input.fade}, 1.0\n sof 1.0, -0.5\n skp neg, fade_neg\n \n ; Fade > 0.5 path\n clr\n rdax ${input.fade}, 0.586\n sof 1.0, 0.414\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n \n rdax ${input.fade}, 1.0\n sof 0.707, -0.707\n sof -2.0, 0.0\n mulx ${input.input1}\n rdax ${reg.temp}, 1.0\n skp run, fade_done\n\n fade_neg:\n ; Fade < 0.5 path\n clr\n rdax ${input.fade}, 1.414\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n \n rdax ${input.fade}, -0.586\n sof 0.999, 0.999\n mulx ${input.input1}\n rdax ${reg.temp}, 1.0\n\n fade_done:\n wrax ${output.output}, 0.0\n @endif\n@else\n ; Fallback to simple crossfade using parameter\n @equals staticFade ${fade}\n @equals staticInvFade (1.0 - ${fade})\n @if pinConnected(input1)\n rdax ${input.input1}, ${staticInvFade}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${staticFade}\n @endif\n wrax ${output.output}, 0.0\n@endif",
|
|
4406
|
+
"_rawAtl": "---\n{\n \"type\": \"math.crossfade3\",\n \"name\": \"Crossfade 3\",\n \"category\": \"Gain/Mixing\",\n \"description\": \"True crossfade between two inputs with control and parameter fallback\",\n \"color\": \"#4287f5\",\n \"inputs\": [\n { \"id\": \"input1\", \"name\": \"Input 1\", \"type\": \"audio\", \"required\": true },\n { \"id\": \"input2\", \"name\": \"Input 2\", \"type\": \"audio\", \"required\": true },\n { \"id\": \"fade\", \"name\": \"Fade\", \"type\": \"control\", \"required\": false }\n ],\n \"outputs\": [\n { \"id\": \"output\", \"name\": \"Output\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n { \"id\": \"fade\", \"name\": \"Fade\", \"type\": \"number\", \"default\": 0.5, \"min\": 0, \"max\": 1, \"step\": 0.01 }\n ],\n \"registers\": [ \"temp\" ]\n}\n---\n; Crossfade 3 (Restored Java logic)\n@section main\n\n@if pinConnected(fade)\n @if pinConnected(input1) && pinConnected(input2)\n rdax ${input.fade}, 1.0\n sof 1.0, -0.5\n skp neg, fade_neg\n \n ; Fade > 0.5 path\n clr\n rdax ${input.fade}, 0.586\n sof 1.0, 0.414\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n \n rdax ${input.fade}, 1.0\n sof 0.707, -0.707\n sof -2.0, 0.0\n mulx ${input.input1}\n rdax ${reg.temp}, 1.0\n skp run, fade_done\n\n fade_neg:\n ; Fade < 0.5 path\n clr\n rdax ${input.fade}, 1.414\n mulx ${input.input2}\n wrax ${reg.temp}, 0.0\n \n rdax ${input.fade}, -0.586\n sof 0.999, 0.999\n mulx ${input.input1}\n rdax ${reg.temp}, 1.0\n\n fade_done:\n wrax ${output.output}, 0.0\n @endif\n@else\n ; Fallback to simple crossfade using parameter\n @equals staticFade ${fade}\n @equals staticInvFade (1.0 - ${fade})\n @if pinConnected(input1)\n rdax ${input.input1}, ${staticInvFade}\n @endif\n @if pinConnected(input2)\n rdax ${input.input2}, ${staticFade}\n @endif\n wrax ${output.output}, 0.0\n@endif\n"
|
|
4407
4407
|
},
|
|
4408
4408
|
{
|
|
4409
4409
|
"type": "math.gainboost",
|
|
@@ -4440,8 +4440,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4440
4440
|
"description": "Number of 6dB gain stages."
|
|
4441
4441
|
}
|
|
4442
4442
|
],
|
|
4443
|
-
"template": "; Gain Boost (Restored Java logic)\
|
|
4444
|
-
"_rawAtl": "---\
|
|
4443
|
+
"template": "; Gain Boost (Restored Java logic)\n@section main\n\nrdax ${input.in}, 1.0\n\n; Each 'sof -2.0, 0' adds 6dB but flips phase\n@if param.gain >= 1\nsof -2.0, 0.0\n@endif\n@if param.gain >= 2\nsof -2.0, 0.0\n@endif\n@if param.gain >= 3\nsof -2.0, 0.0\n@endif\n@if param.gain >= 4\nsof -2.0, 0.0\n@endif\n\n; If an odd number of stages was used, flip phase back to original\n@if (param.gain % 2) == 1\nsof -1.0, 0.0\n@endif\n\nwrax ${output.out}, 0.0",
|
|
4444
|
+
"_rawAtl": "---\n{\n \"type\": \"math.gainboost\",\n \"name\": \"Gain Boost\",\n \"category\": \"Gain/Mixing\",\n \"description\": \"Adjusts the gain of an audio signal in 6dB steps with correct phase logic.\",\n \"color\": \"#4287f5\",\n \"width\": 100,\n \"labelTemplate\": \"${param.gain * 6} dB\",\n \"inputs\": [\n { \"id\": \"in\", \"name\": \"In\", \"type\": \"audio\", \"required\": true }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Out\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"gain\",\n \"name\": \"Boost (6dB steps)\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": 0,\n \"max\": 4,\n \"step\": 1,\n \"description\": \"Number of 6dB gain stages.\"\n }\n ]\n}\n---\n; Gain Boost (Restored Java logic)\n@section main\n\nrdax ${input.in}, 1.0\n\n; Each 'sof -2.0, 0' adds 6dB but flips phase\n@if param.gain >= 1\nsof -2.0, 0.0\n@endif\n@if param.gain >= 2\nsof -2.0, 0.0\n@endif\n@if param.gain >= 3\nsof -2.0, 0.0\n@endif\n@if param.gain >= 4\nsof -2.0, 0.0\n@endif\n\n; If an odd number of stages was used, flip phase back to original\n@if (param.gain % 2) == 1\nsof -1.0, 0.0\n@endif\n\nwrax ${output.out}, 0.0\n"
|
|
4445
4445
|
},
|
|
4446
4446
|
{
|
|
4447
4447
|
"type": "math.mixer2",
|
|
@@ -4498,8 +4498,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4498
4498
|
}
|
|
4499
4499
|
],
|
|
4500
4500
|
"color": "#2468f2",
|
|
4501
|
-
"template": "@section main\
|
|
4502
|
-
"_rawAtl": "---\
|
|
4501
|
+
"template": "@section main\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1}\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif",
|
|
4502
|
+
"_rawAtl": "---\n{\n \"type\": \"math.mixer2\",\n \"category\": \"Gain/Mixing\",\n \"name\": \"2:1 Mixer\",\n \"description\": \"Mixes 2 audio inputs with optional gain control\",\n \"inputs\": [\n {\n \"id\": \"input1\",\n \"name\": \"Input 1\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input2\",\n \"name\": \"Input 2\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"level_1\",\n \"name\": \"Level 1\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_2\",\n \"name\": \"Level 2\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"gain1\",\n \"name\": \"Input Gain 1\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain2\",\n \"name\": \"Input Gain 2\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"color\": \"#2468f2\"\n}\n---\n@section main\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1}\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif\n"
|
|
4503
4503
|
},
|
|
4504
4504
|
{
|
|
4505
4505
|
"type": "math.mixer3",
|
|
@@ -4575,8 +4575,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4575
4575
|
}
|
|
4576
4576
|
],
|
|
4577
4577
|
"color": "#2468f2",
|
|
4578
|
-
"template": "@section main\
|
|
4579
|
-
"_rawAtl": "---\
|
|
4578
|
+
"template": "@section main\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1}\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 3)\n\trdax ${input.input3}, ${gain3}\n@if pinConnected(Level 3)\n\t\tmulx ${input.level_3}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif",
|
|
4579
|
+
"_rawAtl": "---\n{\n \"type\": \"math.mixer3\",\n \"category\": \"Gain/Mixing\",\n \"name\": \"3:1 Mixer\",\n \"description\": \"Mixes 3 audio inputs with optional gain control\",\n \"inputs\": [\n {\n \"id\": \"input1\",\n \"name\": \"Input 1\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input2\",\n \"name\": \"Input 2\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input3\",\n \"name\": \"Input 3\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"level_1\",\n \"name\": \"Level 1\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_2\",\n \"name\": \"Level 2\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_3\",\n \"name\": \"Level 3\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"gain1\",\n \"name\": \"Input Gain 1\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain2\",\n \"name\": \"Input Gain 2\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain3\",\n \"name\": \"Input Gain 3\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"color\": \"#2468f2\"\n}\n---\n@section main\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1}\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 3)\n\trdax ${input.input3}, ${gain3}\n@if pinConnected(Level 3)\n\t\tmulx ${input.level_3}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif\n"
|
|
4580
4580
|
},
|
|
4581
4581
|
{
|
|
4582
4582
|
"type": "math.mixer4",
|
|
@@ -4671,8 +4671,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4671
4671
|
}
|
|
4672
4672
|
],
|
|
4673
4673
|
"color": "#2468f2",
|
|
4674
|
-
"template": "@section header\
|
|
4675
|
-
"_rawAtl": "---\
|
|
4674
|
+
"template": "@section header\n@comment \"Generated from spincad source file Mixer_4_to_1.spincad\"\n\n@section main\n;REGISTERS \n// we dont read input 1 unless it's connected\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1} ;read input signal\n// if level 1 is connected we multiply by level 1\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 3)\n\trdax ${input.input3}, ${gain3}\n@if pinConnected(Level 3)\n\t\tmulx ${input.level_3}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 4)\n\trdax ${input.input4}, ${gain4}\n@if pinConnected(Level 4)\n\t\tmulx ${input.level_4}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 3)\n\t\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif",
|
|
4675
|
+
"_rawAtl": "---\n{\n \"type\": \"math.mixer4\",\n \"category\": \"Gain/Mixing\",\n \"name\": \"4:1 Mixer\",\n \"description\": \"Mixes 4 audio inputs with optional gain control\",\n \"inputs\": [\n {\n \"id\": \"input1\",\n \"name\": \"Input 1\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input2\",\n \"name\": \"Input 2\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input3\",\n \"name\": \"Input 3\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"input4\",\n \"name\": \"Input 4\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"level_1\",\n \"name\": \"Level 1\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_2\",\n \"name\": \"Level 2\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_3\",\n \"name\": \"Level 3\",\n \"type\": \"control\"\n },\n {\n \"id\": \"level_4\",\n \"name\": \"Level 4\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"gain1\",\n \"name\": \"Input Gain 1\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain2\",\n \"name\": \"Input Gain 2\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain3\",\n \"name\": \"Input Gain 3\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n },\n {\n \"id\": \"gain4\",\n \"name\": \"Input Gain 4\",\n \"type\": \"number\",\n \"min\": -18,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"color\": \"#2468f2\"\n}\n---\n@section header\n@comment \"Generated from spincad source file Mixer_4_to_1.spincad\"\n\n@section main\n;REGISTERS \n// we dont read input 1 unless it's connected\n@if pinConnected(Input 1)\n\trdax ${input.input1}, ${gain1} ;read input signal\n// if level 1 is connected we multiply by level 1\n@if pinConnected(Level 1)\n\t\tmulx ${input.level_1}\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 2)\n\trdax ${input.input2}, ${gain2}\n@if pinConnected(Level 2)\n\t\tmulx ${input.level_2}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 3)\n\trdax ${input.input3}, ${gain3}\n@if pinConnected(Level 3)\n\t\tmulx ${input.level_3}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif\n@if pinConnected(Input 4)\n\trdax ${input.input4}, ${gain4}\n@if pinConnected(Level 4)\n\t\tmulx ${input.level_4}\n@endif\n@if pinConnected(Input 1)\n\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 2)\n\t\t\trdax ${output.output}, 1.0\n@else\n@if pinConnected(Input 3)\n\t\t\t\trdax ${output.output}, 1.0\n@endif\n@endif\n@endif\n\twrax ${output.output}, 0.0\n@endif"
|
|
4676
4676
|
},
|
|
4677
4677
|
{
|
|
4678
4678
|
"type": "math.volume",
|
|
@@ -4710,8 +4710,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4710
4710
|
}
|
|
4711
4711
|
],
|
|
4712
4712
|
"color": "#2468f2",
|
|
4713
|
-
"template": "@section header\
|
|
4714
|
-
"_rawAtl": "---\
|
|
4713
|
+
"template": "@section header\n@comment \"Generated from spincad source file ${input.volume}.spincad\"\n\n@section main\n;REGISTERS \n@if pinConnected(${input.input})\nrdax ${input.input}, ${gain} ;read ${input.input} signal\n@if pinConnected(${input.volume})\nmulx ${input.volume}\n@endif\nwrax ${output.output},0 ;${output.output} in ACC and lf1 \n@endif",
|
|
4714
|
+
"_rawAtl": "---\n{\n \"type\": \"math.volume\",\n \"category\": \"Gain/Mixing\",\n \"name\": \"Volume\",\n \"description\": \"Applies a gain to the input signal\",\n \"inputs\": [\n {\n \"id\": \"input\",\n \"name\": \"Input\",\n \"type\": \"audio\"\n },\n {\n \"id\": \"volume\",\n \"name\": \"Volume\",\n \"type\": \"control\"\n }\n ],\n \"outputs\": [\n {\n \"id\": \"output\",\n \"name\": \"Output\",\n \"type\": \"audio\"\n }\n ],\n \"parameters\": [\n {\n \"id\": \"gain\",\n \"name\": \"Input Gain\",\n \"type\": \"number\",\n \"min\": -24,\n \"max\": 0,\n \"default\": -6,\n \"conversion\": \"DBLEVEL\"\n }\n ],\n \"color\": \"#2468f2\"\n}\n---\n@section header\n@comment \"Generated from spincad source file ${input.volume}.spincad\"\n\n@section main\n;REGISTERS \n@if pinConnected(${input.input})\nrdax ${input.input}, ${gain} ;read ${input.input} signal\n@if pinConnected(${input.volume})\nmulx ${input.volume}\n@endif\nwrax ${output.output},0 ;${output.output} in ACC and lf1 \n@endif"
|
|
4715
4715
|
},
|
|
4716
4716
|
{
|
|
4717
4717
|
"type": "other.stickynote",
|
|
@@ -4734,7 +4734,7 @@ export const BUILTIN_BLOCKS = [
|
|
|
4734
4734
|
],
|
|
4735
4735
|
"labelTemplate": "${param.text}",
|
|
4736
4736
|
"template": "@comment ${param.text}",
|
|
4737
|
-
"_rawAtl": "---\
|
|
4737
|
+
"_rawAtl": "---\n{\n \"type\": \"other.stickynote\",\n \"name\": \"Sticky Note\",\n \"category\": \"Other\",\n \"description\": \"Add documentation comments to your diagram\",\n \"color\": \"#FFEB3B\",\n \"width\": 120,\n \"inputs\": [],\n \"outputs\": [],\n \"parameters\": [\n {\n \"id\": \"text\",\n \"name\": \"Note\",\n \"type\": \"string\",\n \"default\": \"Add your notes here...\",\n \"multiline\": true,\n \"description\": \"Text content for the sticky note. Will be added as comments in the assembly output.\"\n }\n ],\n \"labelTemplate\": \"${param.text}\"\n}\n---\n@comment ${param.text}\n"
|
|
4738
4738
|
},
|
|
4739
4739
|
{
|
|
4740
4740
|
"type": "other.tonegen",
|
|
@@ -4806,8 +4806,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4806
4806
|
"p2fil",
|
|
4807
4807
|
"amp"
|
|
4808
4808
|
],
|
|
4809
|
-
"template": "@section init\
|
|
4810
|
-
"_rawAtl": "---\
|
|
4809
|
+
"template": "@section init\n; Tone Generator init\nskp run, tonegen_adjustable_init\nsof 0.0, 0.5\nwrax ${reg.s}, 0.0\ntonegen_adjustable_init:\n\n@section main\n; Sine Wave Generator (rotation matrix, 4x oversampled)\n\n; Calculate frequency\n@if pinConnected(fine_freq)\nrdax ${input.fine_freq}, 1.0\n@else\nsof 0.0, ${fineFreq}\n@endif\nsof 0.01, -0.005\n\n@if pinConnected(coarse_freq)\nrdax ${input.coarse_freq}, 0.625\n@else\nsof 1.0, (${param.coarseFreq} * 0.625)\n@endif\nsof 1.0, -0.66\nexp 1.0, 0.0\n\n; Filter the frequency control\nrdfx ${reg.p0fil}, 0.01\nwrax ${reg.p0fil}, 1.0\nwrax ${reg.freq}, 0.0\n\n; Calculate amplitude (dB/step)\n@if pinConnected(amplitude)\nrdax ${input.amplitude}, 0.9375\n@else\nsof 0.0, (${amplitude} * 0.9375)\n@endif\n\n; Filter amplitude control\nrdfx ${reg.p2fil}, 0.01\nwrax ${reg.p2fil}, 1.0\nsof 1.0, -0.9375\nexp 1.0, 0.0\nwrax ${reg.amp}, 0.0\n\n; Rotation matrix oscillator (4x oversampled)\n\n; Iteration 1\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 2\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 3\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 4 (final - accumulate in ACC)\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 1.99\n\n; Scale output by amplitude\nmulx ${reg.amp}\n\n; Write to output\nwrax ${output.out}, 0.0",
|
|
4810
|
+
"_rawAtl": "---\n{\n \"type\": \"other.tonegen\",\n \"category\": \"Other\",\n \"name\": \"Tone Generator\",\n \"description\": \"Sine wave generator with rotation matrix oscillator (4x oversampled) based on Spin Semi sample code\",\n \"color\": \"#FF9800\",\n \"inputs\": [\n { \"id\": \"coarse_freq\", \"name\": \"Coarse Freq\", \"type\": \"control\", \"required\": false },\n { \"id\": \"fine_freq\", \"name\": \"Fine Freq\", \"type\": \"control\", \"required\": false },\n { \"id\": \"amplitude\", \"name\": \"Amplitude\", \"type\": \"control\", \"required\": false }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Output\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"coarseFreq\",\n \"name\": \"Coarse Frequency\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n },\n {\n \"id\": \"fineFreq\",\n \"name\": \"Fine Frequency\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n },\n {\n \"id\": \"amplitude\",\n \"name\": \"Amplitude\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"freq\", \"s\", \"c\", \"p0fil\", \"p2fil\", \"amp\"\n ]\n}\n---\n@section init\n; Tone Generator init\nskp run, tonegen_adjustable_init\nsof 0.0, 0.5\nwrax ${reg.s}, 0.0\ntonegen_adjustable_init:\n\n@section main\n; Sine Wave Generator (rotation matrix, 4x oversampled)\n\n; Calculate frequency\n@if pinConnected(fine_freq)\nrdax ${input.fine_freq}, 1.0\n@else\nsof 0.0, ${fineFreq}\n@endif\nsof 0.01, -0.005\n\n@if pinConnected(coarse_freq)\nrdax ${input.coarse_freq}, 0.625\n@else\nsof 1.0, (${param.coarseFreq} * 0.625)\n@endif\nsof 1.0, -0.66\nexp 1.0, 0.0\n\n; Filter the frequency control\nrdfx ${reg.p0fil}, 0.01\nwrax ${reg.p0fil}, 1.0\nwrax ${reg.freq}, 0.0\n\n; Calculate amplitude (dB/step)\n@if pinConnected(amplitude)\nrdax ${input.amplitude}, 0.9375\n@else\nsof 0.0, (${amplitude} * 0.9375)\n@endif\n\n; Filter amplitude control\nrdfx ${reg.p2fil}, 0.01\nwrax ${reg.p2fil}, 1.0\nsof 1.0, -0.9375\nexp 1.0, 0.0\nwrax ${reg.amp}, 0.0\n\n; Rotation matrix oscillator (4x oversampled)\n\n; Iteration 1\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 2\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 3\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 4 (final - accumulate in ACC)\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 1.99\n\n; Scale output by amplitude\nmulx ${reg.amp}\n\n; Write to output\nwrax ${output.out}, 0.0\n"
|
|
4811
4811
|
},
|
|
4812
4812
|
{
|
|
4813
4813
|
"type": "other.tonegen.fixed",
|
|
@@ -4858,8 +4858,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4858
4858
|
"p2fil",
|
|
4859
4859
|
"amp"
|
|
4860
4860
|
],
|
|
4861
|
-
"template": "@section init\
|
|
4862
|
-
"_rawAtl": "---\
|
|
4861
|
+
"template": "@section init\n; Tone Generator (Fixed) init\nskp run, tonegen_fixed_init\nsof 0.0, 0.5\nwrax ${reg.s}, 0.0\n; The angle for frequency is approx (2*PI*freq) / (SampleRate*4) \nsof 0.0, (6.2831853 * ${frequency}) / 131072.0\nwrax ${reg.freq}, 0.0\ntonegen_fixed_init:\n\n@section main\n; Sine Wave Generator - ${frequency} Hz (fixed)\n\n; Calculate amplitude (dB/step)\n@if pinConnected(amplitude)\nrdax ${input.amplitude}, 0.9375\n@else\nsof 0.0, (${amplitude} * 0.9375)\n@endif\n\n; Filter amplitude control\nrdfx ${reg.p2fil}, 0.01\nwrax ${reg.p2fil}, 1.0\nsof 1.0, -0.9375\nexp 1.0, 0.0\nwrax ${reg.amp}, 0.0\n\n; Rotation matrix oscillator (4x oversampled)\n\n; Iteration 1\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 2\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 3\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 4 (final - accumulate in ACC)\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 1.99\n\n; Scale output by amplitude\nmulx ${reg.amp}\n\n; Write to output\nwrax ${output.out}, 0.0",
|
|
4862
|
+
"_rawAtl": "---\n{\n \"type\": \"other.tonegen.fixed\",\n \"category\": \"Other\",\n \"name\": \"Tone Generator (Fixed)\",\n \"description\": \"Fixed frequency sine wave generator with amplitude control\",\n \"color\": \"#FF9800\",\n \"labelTemplate\": \"${param.frequency} Hz\",\n \"inputs\": [\n { \"id\": \"amplitude\", \"name\": \"Amplitude\", \"type\": \"control\", \"required\": false }\n ],\n \"outputs\": [\n { \"id\": \"out\", \"name\": \"Output\", \"type\": \"audio\" }\n ],\n \"parameters\": [\n {\n \"id\": \"frequency\",\n \"name\": \"Frequency\",\n \"type\": \"number\",\n \"default\": 440,\n \"min\": 20,\n \"max\": 10000,\n \"step\": 1\n },\n {\n \"id\": \"amplitude\",\n \"name\": \"Amplitude\",\n \"type\": \"number\",\n \"default\": 0.5,\n \"min\": 0.0,\n \"max\": 1.0,\n \"step\": 0.01\n }\n ],\n \"registers\": [\n \"freq\", \"s\", \"c\", \"p2fil\", \"amp\"\n ]\n}\n---\n@section init\n; Tone Generator (Fixed) init\nskp run, tonegen_fixed_init\nsof 0.0, 0.5\nwrax ${reg.s}, 0.0\n; The angle for frequency is approx (2*PI*freq) / (SampleRate*4) \nsof 0.0, (6.2831853 * ${frequency}) / 131072.0\nwrax ${reg.freq}, 0.0\ntonegen_fixed_init:\n\n@section main\n; Sine Wave Generator - ${frequency} Hz (fixed)\n\n; Calculate amplitude (dB/step)\n@if pinConnected(amplitude)\nrdax ${input.amplitude}, 0.9375\n@else\nsof 0.0, (${amplitude} * 0.9375)\n@endif\n\n; Filter amplitude control\nrdfx ${reg.p2fil}, 0.01\nwrax ${reg.p2fil}, 1.0\nsof 1.0, -0.9375\nexp 1.0, 0.0\nwrax ${reg.amp}, 0.0\n\n; Rotation matrix oscillator (4x oversampled)\n\n; Iteration 1\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 2\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 3\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 0.0\n\n; Iteration 4 (final - accumulate in ACC)\nrdax ${reg.c}, 1.0\nmulx ${reg.freq}\nrdax ${reg.s}, 1.0\nwrax ${reg.s}, -1.0\nmulx ${reg.freq}\nrdax ${reg.c}, 1.0\nwrax ${reg.c}, 1.99\n\n; Scale output by amplitude\nmulx ${reg.amp}\n\n; Write to output\nwrax ${output.out}, 0.0\n"
|
|
4863
4863
|
},
|
|
4864
4864
|
{
|
|
4865
4865
|
"type": "output.dac",
|
|
@@ -4905,8 +4905,8 @@ export const BUILTIN_BLOCKS = [
|
|
|
4905
4905
|
"step": 0.01
|
|
4906
4906
|
}
|
|
4907
4907
|
],
|
|
4908
|
-
"template": "@section output\
|
|
4909
|
-
"_rawAtl": "---\
|
|
4908
|
+
"template": "@section output\n\n; DAC Output\nrdax ${input.in}, 1.0\n\n@if gain != 1.0\nsof ${param.gain}, 0.0\n@endif\n\n@if dacNumber == 0\nwrax DACL, 0\n@else\nwrax DACR, 0\n@endif",
|
|
4909
|
+
"_rawAtl": "---\n{\n \"type\": \"output.dac\",\n \"name\": \"DAC Output\",\n \"category\": \"Input/Output\",\n \"description\": \"Writes audio to an analog output (DAC) with adjustable gain.\",\n \"color\": \"#F44336\",\n \"width\": 150,\n \"inputs\": [\n {\n \"id\": \"in\",\n \"name\": \"Audio\",\n \"type\": \"audio\",\n \"required\": true\n }\n ],\n \"outputs\": [],\n \"labelTemplate\": \"DAC ${param.dacNumber == 0 ? 'L' : 'R'}\",\n \"parameters\": [\n {\n \"id\": \"dacNumber\",\n \"name\": \"DAC Number\",\n \"type\": \"select\",\n \"default\": 0,\n \"options\": [\n {\n \"label\": \"DACL\",\n \"value\": 0\n },\n {\n \"label\": \"DACR\",\n \"value\": 1\n }\n ]\n },\n {\n \"id\": \"gain\",\n \"name\": \"Gain\",\n \"type\": \"number\",\n \"default\": 1,\n \"min\": -2,\n \"max\": 1.9999,\n \"step\": 0.01\n }\n ]\n}\n---\n@section output\n\n; DAC Output\nrdax ${input.in}, 1.0\n\n@if gain != 1.0\nsof ${param.gain}, 0.0\n@endif\n\n@if dacNumber == 0\nwrax DACL, 0\n@else\nwrax DACR, 0\n@endif\n"
|
|
4910
4910
|
}
|
|
4911
4911
|
];
|
|
4912
4912
|
//# sourceMappingURL=builtinBlocks.js.map
|