@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
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
---
|
|
2
|
-
{
|
|
3
|
-
"type": "filter.hpf_1p",
|
|
4
|
-
"category": "Filter",
|
|
5
|
-
"name": "1P HPF",
|
|
6
|
-
"description": "1-pole high pass filter",
|
|
7
|
-
"inputs": [
|
|
8
|
-
{
|
|
9
|
-
"id": "input",
|
|
10
|
-
"name": "Input",
|
|
11
|
-
"type": "audio"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id": "freqControl",
|
|
15
|
-
"name": "Frequency",
|
|
16
|
-
"type": "control"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"outputs": [
|
|
20
|
-
{
|
|
21
|
-
"id": "output",
|
|
22
|
-
"name": "Output",
|
|
23
|
-
"type": "audio"
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
"parameters": [
|
|
27
|
-
{
|
|
28
|
-
"id": "freq",
|
|
29
|
-
"name": "Frequency",
|
|
30
|
-
"type": "number",
|
|
31
|
-
"min": 40,
|
|
32
|
-
"max": 3500,
|
|
33
|
-
"default": 100,
|
|
34
|
-
"conversion": "LOGFREQ"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"color": "#24f26f",
|
|
38
|
-
"registers": [
|
|
39
|
-
"lpf1"
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
---
|
|
43
|
-
@section header
|
|
44
|
-
@comment "Generated from spincad source file HPF_RDFX.spincad"
|
|
45
|
-
|
|
46
|
-
@section main
|
|
47
|
-
// variable - Name - low - high - multiplier - precision - option
|
|
48
|
-
@if pinConnected(${input.input})
|
|
49
|
-
@if pinConnected(Frequency)
|
|
50
|
-
rdax ${input.input}, ${freq}
|
|
51
|
-
rdax ${reg.lpf1}, -${freq}
|
|
52
|
-
mulx ${input.freqControl}
|
|
53
|
-
rdax ${reg.lpf1}, 1.0
|
|
54
|
-
@else
|
|
55
|
-
rdax ${input.input}, 1.0
|
|
56
|
-
rdfx ${reg.lpf1}, ${freq}
|
|
57
|
-
@endif
|
|
58
|
-
wrax ${reg.lpf1}, -1.0
|
|
59
|
-
// do a lowpass filter then subtract that from the ${input.input}.
|
|
60
|
-
// voila high pass filter!
|
|
61
|
-
rdax ${input.input}, 1.0
|
|
62
|
-
wrax ${output.output}, 0
|
|
1
|
+
---
|
|
2
|
+
{
|
|
3
|
+
"type": "filter.hpf_1p",
|
|
4
|
+
"category": "Filter",
|
|
5
|
+
"name": "1P HPF",
|
|
6
|
+
"description": "1-pole high pass filter",
|
|
7
|
+
"inputs": [
|
|
8
|
+
{
|
|
9
|
+
"id": "input",
|
|
10
|
+
"name": "Input",
|
|
11
|
+
"type": "audio"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "freqControl",
|
|
15
|
+
"name": "Frequency",
|
|
16
|
+
"type": "control"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"outputs": [
|
|
20
|
+
{
|
|
21
|
+
"id": "output",
|
|
22
|
+
"name": "Output",
|
|
23
|
+
"type": "audio"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"parameters": [
|
|
27
|
+
{
|
|
28
|
+
"id": "freq",
|
|
29
|
+
"name": "Frequency",
|
|
30
|
+
"type": "number",
|
|
31
|
+
"min": 40,
|
|
32
|
+
"max": 3500,
|
|
33
|
+
"default": 100,
|
|
34
|
+
"conversion": "LOGFREQ"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"color": "#24f26f",
|
|
38
|
+
"registers": [
|
|
39
|
+
"lpf1"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
---
|
|
43
|
+
@section header
|
|
44
|
+
@comment "Generated from spincad source file HPF_RDFX.spincad"
|
|
45
|
+
|
|
46
|
+
@section main
|
|
47
|
+
// variable - Name - low - high - multiplier - precision - option
|
|
48
|
+
@if pinConnected(${input.input})
|
|
49
|
+
@if pinConnected(Frequency)
|
|
50
|
+
rdax ${input.input}, ${freq}
|
|
51
|
+
rdax ${reg.lpf1}, -${freq}
|
|
52
|
+
mulx ${input.freqControl}
|
|
53
|
+
rdax ${reg.lpf1}, 1.0
|
|
54
|
+
@else
|
|
55
|
+
rdax ${input.input}, 1.0
|
|
56
|
+
rdfx ${reg.lpf1}, ${freq}
|
|
57
|
+
@endif
|
|
58
|
+
wrax ${reg.lpf1}, -1.0
|
|
59
|
+
// do a lowpass filter then subtract that from the ${input.input}.
|
|
60
|
+
// voila high pass filter!
|
|
61
|
+
rdax ${input.input}, 1.0
|
|
62
|
+
wrax ${output.output}, 0
|
|
63
63
|
@endif
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
---
|
|
2
|
-
{
|
|
3
|
-
"type": "filter.lpf_1p",
|
|
4
|
-
"category": "Filter",
|
|
5
|
-
"name": "1P LPF",
|
|
6
|
-
"description": "1-pole low pass filter",
|
|
7
|
-
"inputs": [
|
|
8
|
-
{
|
|
9
|
-
"id": "input",
|
|
10
|
-
"name": "Input",
|
|
11
|
-
"type": "audio"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"id": "freqControl",
|
|
15
|
-
"name": "Frequency",
|
|
16
|
-
"type": "control"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"outputs": [
|
|
20
|
-
{
|
|
21
|
-
"id": "lpf1",
|
|
22
|
-
"name": "Output",
|
|
23
|
-
"type": "audio"
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
"parameters": [
|
|
27
|
-
{
|
|
28
|
-
"id": "freq",
|
|
29
|
-
"name": "Frequency",
|
|
30
|
-
"type": "number",
|
|
31
|
-
"min": 80,
|
|
32
|
-
"max": 5000,
|
|
33
|
-
"default": 100,
|
|
34
|
-
"conversion": "LOGFREQ"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"color": "#24f26f",
|
|
38
|
-
"registers": [
|
|
39
|
-
"output"
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
---
|
|
43
|
-
@section header
|
|
44
|
-
@comment "Generated from spincad source file LPF_RDFX.spincad"
|
|
45
|
-
|
|
46
|
-
@section main
|
|
47
|
-
// variable - Name - low - high - multiplier - precision - option
|
|
48
|
-
@if pinConnected(${input.input})
|
|
49
|
-
@if pinConnected(Frequency)
|
|
50
|
-
rdax ${input.input}, ${freq}
|
|
51
|
-
rdax ${output.lpf1}, -${freq}
|
|
52
|
-
mulx ${input.freqControl}
|
|
53
|
-
rdax ${output.lpf1}, 1.0
|
|
54
|
-
@else
|
|
55
|
-
rdax ${input.input}, 1.0
|
|
56
|
-
rdfx ${output.lpf1}, ${freq}
|
|
57
|
-
@endif
|
|
58
|
-
wrax ${output.lpf1}, 0
|
|
1
|
+
---
|
|
2
|
+
{
|
|
3
|
+
"type": "filter.lpf_1p",
|
|
4
|
+
"category": "Filter",
|
|
5
|
+
"name": "1P LPF",
|
|
6
|
+
"description": "1-pole low pass filter",
|
|
7
|
+
"inputs": [
|
|
8
|
+
{
|
|
9
|
+
"id": "input",
|
|
10
|
+
"name": "Input",
|
|
11
|
+
"type": "audio"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "freqControl",
|
|
15
|
+
"name": "Frequency",
|
|
16
|
+
"type": "control"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"outputs": [
|
|
20
|
+
{
|
|
21
|
+
"id": "lpf1",
|
|
22
|
+
"name": "Output",
|
|
23
|
+
"type": "audio"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"parameters": [
|
|
27
|
+
{
|
|
28
|
+
"id": "freq",
|
|
29
|
+
"name": "Frequency",
|
|
30
|
+
"type": "number",
|
|
31
|
+
"min": 80,
|
|
32
|
+
"max": 5000,
|
|
33
|
+
"default": 100,
|
|
34
|
+
"conversion": "LOGFREQ"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"color": "#24f26f",
|
|
38
|
+
"registers": [
|
|
39
|
+
"output"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
---
|
|
43
|
+
@section header
|
|
44
|
+
@comment "Generated from spincad source file LPF_RDFX.spincad"
|
|
45
|
+
|
|
46
|
+
@section main
|
|
47
|
+
// variable - Name - low - high - multiplier - precision - option
|
|
48
|
+
@if pinConnected(${input.input})
|
|
49
|
+
@if pinConnected(Frequency)
|
|
50
|
+
rdax ${input.input}, ${freq}
|
|
51
|
+
rdax ${output.lpf1}, -${freq}
|
|
52
|
+
mulx ${input.freqControl}
|
|
53
|
+
rdax ${output.lpf1}, 1.0
|
|
54
|
+
@else
|
|
55
|
+
rdax ${input.input}, 1.0
|
|
56
|
+
rdfx ${output.lpf1}, ${freq}
|
|
57
|
+
@endif
|
|
58
|
+
wrax ${output.lpf1}, 0
|
|
59
59
|
@endif
|
|
@@ -1,207 +1,207 @@
|
|
|
1
|
-
---
|
|
2
|
-
{
|
|
3
|
-
"type": "filter.auto_wah",
|
|
4
|
-
"name": "Auto-Wah",
|
|
5
|
-
"category": "Filter",
|
|
6
|
-
"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.",
|
|
7
|
-
"color": "#f26724",
|
|
8
|
-
"width": 180,
|
|
9
|
-
"inputs": [
|
|
10
|
-
{
|
|
11
|
-
"id": "in",
|
|
12
|
-
"name": "Input",
|
|
13
|
-
"type": "audio",
|
|
14
|
-
"required": true
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"id": "sensitivity_cv",
|
|
18
|
-
"name": "Sensitivity",
|
|
19
|
-
"type": "control",
|
|
20
|
-
"required": false,
|
|
21
|
-
"parameter": "sensitivity"
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"id": "resonance_cv",
|
|
25
|
-
"name": "Resonance",
|
|
26
|
-
"type": "control",
|
|
27
|
-
"required": false,
|
|
28
|
-
"parameter": "resonance"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": "mix_cv",
|
|
32
|
-
"name": "Mix",
|
|
33
|
-
"type": "control",
|
|
34
|
-
"required": false,
|
|
35
|
-
"parameter": "mix"
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"outputs": [
|
|
39
|
-
{
|
|
40
|
-
"id": "out",
|
|
41
|
-
"name": "Output",
|
|
42
|
-
"type": "audio"
|
|
43
|
-
}
|
|
44
|
-
],
|
|
45
|
-
"parameters": [
|
|
46
|
-
{
|
|
47
|
-
"id": "base_freq",
|
|
48
|
-
"name": "Base Freq",
|
|
49
|
-
"type": "number",
|
|
50
|
-
"default": 300,
|
|
51
|
-
"min": 100,
|
|
52
|
-
"max": 1500,
|
|
53
|
-
"step": 10,
|
|
54
|
-
"conversion": "SVFFREQ",
|
|
55
|
-
"description": "Lowest filter frequency (at silence). Sweep rises above this on transients."
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"id": "sensitivity",
|
|
59
|
-
"name": "Sensitivity",
|
|
60
|
-
"type": "number",
|
|
61
|
-
"default": 0.55,
|
|
62
|
-
"min": 0.0,
|
|
63
|
-
"max": 0.6,
|
|
64
|
-
"step": 0.01,
|
|
65
|
-
"description": "How far the envelope opens the filter. Higher = wider vowel sweep."
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"id": "resonance",
|
|
69
|
-
"name": "Resonance",
|
|
70
|
-
"type": "number",
|
|
71
|
-
"default": 0.82,
|
|
72
|
-
"min": 0.0,
|
|
73
|
-
"max": 0.97,
|
|
74
|
-
"step": 0.01,
|
|
75
|
-
"description": "Filter Q / resonant peak. Higher values add the characteristic vowel quack."
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"id": "attack",
|
|
79
|
-
"name": "Attack",
|
|
80
|
-
"type": "number",
|
|
81
|
-
"default": 0.08,
|
|
82
|
-
"min": 0.01,
|
|
83
|
-
"max": 0.5,
|
|
84
|
-
"step": 0.01,
|
|
85
|
-
"description": "Envelope attack speed. Higher = faster response to pick transients."
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"id": "release",
|
|
89
|
-
"name": "Release",
|
|
90
|
-
"type": "number",
|
|
91
|
-
"default": 0.004,
|
|
92
|
-
"min": 0.001,
|
|
93
|
-
"max": 0.05,
|
|
94
|
-
"step": 0.001,
|
|
95
|
-
"description": "Envelope release speed. Lower = slower filter close after note ends."
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"id": "mix",
|
|
99
|
-
"name": "Dry/Wet Mix",
|
|
100
|
-
"type": "number",
|
|
101
|
-
"default": 1.0,
|
|
102
|
-
"min": 0.0,
|
|
103
|
-
"max": 1.0,
|
|
104
|
-
"step": 0.01
|
|
105
|
-
}
|
|
106
|
-
],
|
|
107
|
-
"registers": [
|
|
108
|
-
"env",
|
|
109
|
-
"bp",
|
|
110
|
-
"lp",
|
|
111
|
-
"freq_reg",
|
|
112
|
-
"damp_reg",
|
|
113
|
-
"sens_reg",
|
|
114
|
-
"mix_reg",
|
|
115
|
-
"dry_val",
|
|
116
|
-
"temp"
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
---
|
|
120
|
-
@section main
|
|
121
|
-
@if pinConnected(in)
|
|
122
|
-
|
|
123
|
-
; ======================================================
|
|
124
|
-
; Stage 0: Save dry signal
|
|
125
|
-
; ======================================================
|
|
126
|
-
rdax ${input.in}, 1.0
|
|
127
|
-
wrax ${reg.dry_val}, 0.0
|
|
128
|
-
|
|
129
|
-
; ======================================================
|
|
130
|
-
; Stage 1: Load CVs
|
|
131
|
-
; ======================================================
|
|
132
|
-
@cv sensitivity_cv
|
|
133
|
-
wrax ${reg.sens_reg}, 0.0
|
|
134
|
-
|
|
135
|
-
@cv resonance_cv
|
|
136
|
-
sof -1.0, 1.0 ; damp = 1 - resonance (high resonance → low damping)
|
|
137
|
-
wrax ${reg.damp_reg}, 0.0
|
|
138
|
-
|
|
139
|
-
@cv mix_cv
|
|
140
|
-
wrax ${reg.mix_reg}, 0.0
|
|
141
|
-
|
|
142
|
-
; ======================================================
|
|
143
|
-
; Stage 2: Envelope Follower (Fast Attack, Slow Release)
|
|
144
|
-
; ======================================================
|
|
145
|
-
rdax ${input.in}, 1.0
|
|
146
|
-
sof 1.99, 0.0 ; 2x pre-boost for detection only — env reaches higher values at normal guitar levels
|
|
147
|
-
absa
|
|
148
|
-
rdax ${reg.env}, -1.0 ; ACC = |input| - env
|
|
149
|
-
skp gez, ${local.ATK}
|
|
150
|
-
; Release path
|
|
151
|
-
sof ${param.release}, 0.0
|
|
152
|
-
skp run, ${local.UPD}
|
|
153
|
-
${local.ATK}:
|
|
154
|
-
sof ${param.attack}, 0.0
|
|
155
|
-
${local.UPD}:
|
|
156
|
-
rdax ${reg.env}, 1.0 ; ACC = delta + env = new env
|
|
157
|
-
wrax ${reg.env}, 0.0
|
|
158
|
-
|
|
159
|
-
; ======================================================
|
|
160
|
-
; Stage 3: Compute Swept Frequency
|
|
161
|
-
; freq = base_freq + env * sensitivity
|
|
162
|
-
; ======================================================
|
|
163
|
-
rdax ${reg.env}, 1.0
|
|
164
|
-
mulx ${reg.sens_reg} ; ACC = env * sensitivity
|
|
165
|
-
sof 1.0, ${param.base_freq} ; ACC = base_freq + env * sensitivity
|
|
166
|
-
wrax ${reg.freq_reg}, 0.0
|
|
167
|
-
|
|
168
|
-
; ======================================================
|
|
169
|
-
; Stage 4: Chamberlin SVF — Bandpass output
|
|
170
|
-
; HP = input - lp - damp*bp
|
|
171
|
-
; bp_new = bp_old + F * HP
|
|
172
|
-
; lp_new = lp_old + F * bp_new
|
|
173
|
-
; ======================================================
|
|
174
|
-
|
|
175
|
-
; Compute (input - lp_old) and save as temp
|
|
176
|
-
rdax ${input.in}, 1.0
|
|
177
|
-
rdax ${reg.lp}, -1.0
|
|
178
|
-
wrax ${reg.temp}, 0.0 ; temp = input - lp_old
|
|
179
|
-
|
|
180
|
-
; Compute HP = (input - lp_old) - damp * bp_old
|
|
181
|
-
rdax ${reg.bp}, 1.0
|
|
182
|
-
mulx ${reg.damp_reg} ; ACC = damp * bp_old
|
|
183
|
-
rdax ${reg.temp}, -1.0 ; ACC = damp*bp_old - (input - lp_old)
|
|
184
|
-
sof -1.0, 0.0 ; ACC = HP = (input - lp_old) - damp*bp_old
|
|
185
|
-
|
|
186
|
-
; bp_new = bp_old + F * HP
|
|
187
|
-
mulx ${reg.freq_reg} ; ACC = F * HP
|
|
188
|
-
rdax ${reg.bp}, 1.0 ; ACC = bp_old + F * HP
|
|
189
|
-
wrax ${reg.bp}, 1.0 ; Save bp_new, keep in ACC
|
|
190
|
-
|
|
191
|
-
; lp_new = lp_old + F * bp_new
|
|
192
|
-
mulx ${reg.freq_reg} ; ACC = F * bp_new
|
|
193
|
-
rdax ${reg.lp}, 1.0 ; ACC = lp_old + F * bp_new
|
|
194
|
-
wrax ${reg.lp}, 0.0 ; Save lp_new
|
|
195
|
-
|
|
196
|
-
; ======================================================
|
|
197
|
-
; Stage 5: Dry/Wet Mix
|
|
198
|
-
; out = dry + (wet - dry) * mix
|
|
199
|
-
; ======================================================
|
|
200
|
-
rdax ${reg.bp}, 0.7 ; Bandpass: vowel/formant peak (dominant)
|
|
201
|
-
rdax ${reg.lp}, 0.3 ; Lowpass: adds fundamental body — pure BP sounds thin
|
|
202
|
-
rdax ${reg.dry_val}, -1.0 ; ACC = wet - dry
|
|
203
|
-
mulx ${reg.mix_reg} ; ACC = (wet - dry) * mix
|
|
204
|
-
rdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix
|
|
205
|
-
wrax ${output.out}, 0.0
|
|
206
|
-
|
|
207
|
-
@endif
|
|
1
|
+
---
|
|
2
|
+
{
|
|
3
|
+
"type": "filter.auto_wah",
|
|
4
|
+
"name": "Auto-Wah",
|
|
5
|
+
"category": "Filter",
|
|
6
|
+
"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.",
|
|
7
|
+
"color": "#f26724",
|
|
8
|
+
"width": 180,
|
|
9
|
+
"inputs": [
|
|
10
|
+
{
|
|
11
|
+
"id": "in",
|
|
12
|
+
"name": "Input",
|
|
13
|
+
"type": "audio",
|
|
14
|
+
"required": true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "sensitivity_cv",
|
|
18
|
+
"name": "Sensitivity",
|
|
19
|
+
"type": "control",
|
|
20
|
+
"required": false,
|
|
21
|
+
"parameter": "sensitivity"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "resonance_cv",
|
|
25
|
+
"name": "Resonance",
|
|
26
|
+
"type": "control",
|
|
27
|
+
"required": false,
|
|
28
|
+
"parameter": "resonance"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "mix_cv",
|
|
32
|
+
"name": "Mix",
|
|
33
|
+
"type": "control",
|
|
34
|
+
"required": false,
|
|
35
|
+
"parameter": "mix"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"outputs": [
|
|
39
|
+
{
|
|
40
|
+
"id": "out",
|
|
41
|
+
"name": "Output",
|
|
42
|
+
"type": "audio"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"parameters": [
|
|
46
|
+
{
|
|
47
|
+
"id": "base_freq",
|
|
48
|
+
"name": "Base Freq",
|
|
49
|
+
"type": "number",
|
|
50
|
+
"default": 300,
|
|
51
|
+
"min": 100,
|
|
52
|
+
"max": 1500,
|
|
53
|
+
"step": 10,
|
|
54
|
+
"conversion": "SVFFREQ",
|
|
55
|
+
"description": "Lowest filter frequency (at silence). Sweep rises above this on transients."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "sensitivity",
|
|
59
|
+
"name": "Sensitivity",
|
|
60
|
+
"type": "number",
|
|
61
|
+
"default": 0.55,
|
|
62
|
+
"min": 0.0,
|
|
63
|
+
"max": 0.6,
|
|
64
|
+
"step": 0.01,
|
|
65
|
+
"description": "How far the envelope opens the filter. Higher = wider vowel sweep."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "resonance",
|
|
69
|
+
"name": "Resonance",
|
|
70
|
+
"type": "number",
|
|
71
|
+
"default": 0.82,
|
|
72
|
+
"min": 0.0,
|
|
73
|
+
"max": 0.97,
|
|
74
|
+
"step": 0.01,
|
|
75
|
+
"description": "Filter Q / resonant peak. Higher values add the characteristic vowel quack."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "attack",
|
|
79
|
+
"name": "Attack",
|
|
80
|
+
"type": "number",
|
|
81
|
+
"default": 0.08,
|
|
82
|
+
"min": 0.01,
|
|
83
|
+
"max": 0.5,
|
|
84
|
+
"step": 0.01,
|
|
85
|
+
"description": "Envelope attack speed. Higher = faster response to pick transients."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "release",
|
|
89
|
+
"name": "Release",
|
|
90
|
+
"type": "number",
|
|
91
|
+
"default": 0.004,
|
|
92
|
+
"min": 0.001,
|
|
93
|
+
"max": 0.05,
|
|
94
|
+
"step": 0.001,
|
|
95
|
+
"description": "Envelope release speed. Lower = slower filter close after note ends."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "mix",
|
|
99
|
+
"name": "Dry/Wet Mix",
|
|
100
|
+
"type": "number",
|
|
101
|
+
"default": 1.0,
|
|
102
|
+
"min": 0.0,
|
|
103
|
+
"max": 1.0,
|
|
104
|
+
"step": 0.01
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"registers": [
|
|
108
|
+
"env",
|
|
109
|
+
"bp",
|
|
110
|
+
"lp",
|
|
111
|
+
"freq_reg",
|
|
112
|
+
"damp_reg",
|
|
113
|
+
"sens_reg",
|
|
114
|
+
"mix_reg",
|
|
115
|
+
"dry_val",
|
|
116
|
+
"temp"
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
---
|
|
120
|
+
@section main
|
|
121
|
+
@if pinConnected(in)
|
|
122
|
+
|
|
123
|
+
; ======================================================
|
|
124
|
+
; Stage 0: Save dry signal
|
|
125
|
+
; ======================================================
|
|
126
|
+
rdax ${input.in}, 1.0
|
|
127
|
+
wrax ${reg.dry_val}, 0.0
|
|
128
|
+
|
|
129
|
+
; ======================================================
|
|
130
|
+
; Stage 1: Load CVs
|
|
131
|
+
; ======================================================
|
|
132
|
+
@cv sensitivity_cv
|
|
133
|
+
wrax ${reg.sens_reg}, 0.0
|
|
134
|
+
|
|
135
|
+
@cv resonance_cv
|
|
136
|
+
sof -1.0, 1.0 ; damp = 1 - resonance (high resonance → low damping)
|
|
137
|
+
wrax ${reg.damp_reg}, 0.0
|
|
138
|
+
|
|
139
|
+
@cv mix_cv
|
|
140
|
+
wrax ${reg.mix_reg}, 0.0
|
|
141
|
+
|
|
142
|
+
; ======================================================
|
|
143
|
+
; Stage 2: Envelope Follower (Fast Attack, Slow Release)
|
|
144
|
+
; ======================================================
|
|
145
|
+
rdax ${input.in}, 1.0
|
|
146
|
+
sof 1.99, 0.0 ; 2x pre-boost for detection only — env reaches higher values at normal guitar levels
|
|
147
|
+
absa
|
|
148
|
+
rdax ${reg.env}, -1.0 ; ACC = |input| - env
|
|
149
|
+
skp gez, ${local.ATK}
|
|
150
|
+
; Release path
|
|
151
|
+
sof ${param.release}, 0.0
|
|
152
|
+
skp run, ${local.UPD}
|
|
153
|
+
${local.ATK}:
|
|
154
|
+
sof ${param.attack}, 0.0
|
|
155
|
+
${local.UPD}:
|
|
156
|
+
rdax ${reg.env}, 1.0 ; ACC = delta + env = new env
|
|
157
|
+
wrax ${reg.env}, 0.0
|
|
158
|
+
|
|
159
|
+
; ======================================================
|
|
160
|
+
; Stage 3: Compute Swept Frequency
|
|
161
|
+
; freq = base_freq + env * sensitivity
|
|
162
|
+
; ======================================================
|
|
163
|
+
rdax ${reg.env}, 1.0
|
|
164
|
+
mulx ${reg.sens_reg} ; ACC = env * sensitivity
|
|
165
|
+
sof 1.0, ${param.base_freq} ; ACC = base_freq + env * sensitivity
|
|
166
|
+
wrax ${reg.freq_reg}, 0.0
|
|
167
|
+
|
|
168
|
+
; ======================================================
|
|
169
|
+
; Stage 4: Chamberlin SVF — Bandpass output
|
|
170
|
+
; HP = input - lp - damp*bp
|
|
171
|
+
; bp_new = bp_old + F * HP
|
|
172
|
+
; lp_new = lp_old + F * bp_new
|
|
173
|
+
; ======================================================
|
|
174
|
+
|
|
175
|
+
; Compute (input - lp_old) and save as temp
|
|
176
|
+
rdax ${input.in}, 1.0
|
|
177
|
+
rdax ${reg.lp}, -1.0
|
|
178
|
+
wrax ${reg.temp}, 0.0 ; temp = input - lp_old
|
|
179
|
+
|
|
180
|
+
; Compute HP = (input - lp_old) - damp * bp_old
|
|
181
|
+
rdax ${reg.bp}, 1.0
|
|
182
|
+
mulx ${reg.damp_reg} ; ACC = damp * bp_old
|
|
183
|
+
rdax ${reg.temp}, -1.0 ; ACC = damp*bp_old - (input - lp_old)
|
|
184
|
+
sof -1.0, 0.0 ; ACC = HP = (input - lp_old) - damp*bp_old
|
|
185
|
+
|
|
186
|
+
; bp_new = bp_old + F * HP
|
|
187
|
+
mulx ${reg.freq_reg} ; ACC = F * HP
|
|
188
|
+
rdax ${reg.bp}, 1.0 ; ACC = bp_old + F * HP
|
|
189
|
+
wrax ${reg.bp}, 1.0 ; Save bp_new, keep in ACC
|
|
190
|
+
|
|
191
|
+
; lp_new = lp_old + F * bp_new
|
|
192
|
+
mulx ${reg.freq_reg} ; ACC = F * bp_new
|
|
193
|
+
rdax ${reg.lp}, 1.0 ; ACC = lp_old + F * bp_new
|
|
194
|
+
wrax ${reg.lp}, 0.0 ; Save lp_new
|
|
195
|
+
|
|
196
|
+
; ======================================================
|
|
197
|
+
; Stage 5: Dry/Wet Mix
|
|
198
|
+
; out = dry + (wet - dry) * mix
|
|
199
|
+
; ======================================================
|
|
200
|
+
rdax ${reg.bp}, 0.7 ; Bandpass: vowel/formant peak (dominant)
|
|
201
|
+
rdax ${reg.lp}, 0.3 ; Lowpass: adds fundamental body — pure BP sounds thin
|
|
202
|
+
rdax ${reg.dry_val}, -1.0 ; ACC = wet - dry
|
|
203
|
+
mulx ${reg.mix_reg} ; ACC = (wet - dry) * mix
|
|
204
|
+
rdax ${reg.dry_val}, 1.0 ; ACC = dry + (wet - dry) * mix
|
|
205
|
+
wrax ${output.out}, 0.0
|
|
206
|
+
|
|
207
|
+
@endif
|