├── .cproject
├── .project
├── Makefile
├── README
├── analogue.png
├── analogue.sh
├── analogue.ttl
├── analogue.xcf
├── faust
├── amps.dsp
├── analogue-poly.dsp
├── analogue.dsp
├── dynamic.dsp
├── effects.dsp
├── filters.dsp
├── freeverb.dsp
├── midi.dsp
├── oscdemo.dsp
├── oscillators.dsp
├── simple.dsp
├── standalone-poly.dsp
├── standalone.dsp
├── test.dsp
├── test2.dsp
└── utils.dsp
├── manifest.ttl
├── portmeta.py
├── src
├── analogue-common.h
├── analogue-gui-test.cpp
├── analogue-gui.cpp
├── analogue.cpp
├── analogue.h
├── changeable.h
├── collector-ui.h
├── comboboxes-test.cpp
├── comboboxes.h
├── dsp.cpp
├── dsp.h
├── dump-rdf.h
├── knob-test.cpp
├── knob.h
├── long-note-test.cpp
├── panel.h
├── printttl.cpp
└── toggle.h
└── test
├── dpw.dsp
├── oscillators.py
├── saw-test.dsp
├── saw2-test.dsp
├── sin-test.dsp
├── sin2-test.dsp
├── square-test.dsp
├── square2-test.dsp
├── tests.cpp
├── tri-test.dsp
└── tri2-test.dsp
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | analogue
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 | ?name?
14 |
15 |
16 |
17 | org.eclipse.cdt.make.core.append_environment
18 | true
19 |
20 |
21 | org.eclipse.cdt.make.core.autoBuildTarget
22 | all
23 |
24 |
25 | org.eclipse.cdt.make.core.buildArguments
26 |
27 |
28 |
29 | org.eclipse.cdt.make.core.buildCommand
30 | make
31 |
32 |
33 | org.eclipse.cdt.make.core.cleanBuildTarget
34 | clean
35 |
36 |
37 | org.eclipse.cdt.make.core.contents
38 | org.eclipse.cdt.make.core.activeConfigSettings
39 |
40 |
41 | org.eclipse.cdt.make.core.enableAutoBuild
42 | false
43 |
44 |
45 | org.eclipse.cdt.make.core.enableCleanBuild
46 | true
47 |
48 |
49 | org.eclipse.cdt.make.core.enableFullBuild
50 | true
51 |
52 |
53 | org.eclipse.cdt.make.core.fullBuildTarget
54 | all
55 |
56 |
57 | org.eclipse.cdt.make.core.stopOnError
58 | true
59 |
60 |
61 | org.eclipse.cdt.make.core.useDefaultBuildCmd
62 | true
63 |
64 |
65 |
66 |
67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
68 | full,incremental,
69 |
70 |
71 |
72 |
73 |
74 | org.eclipse.cdt.core.cnature
75 | org.eclipse.cdt.core.ccnature
76 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
78 |
79 |
80 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | BUNDLE = Analogue.lv2
2 | INSTALL_DIR = /usr/local/lib/lv2
3 | ALSA_GTK = `pkg-config --cflags --libs alsa` `pkg-config --cflags --libs gtk+-2.0`
4 | JACK_GTK = `pkg-config --cflags --libs jack` `pkg-config --cflags --libs gtk+-2.0`
5 | GTKMM = `pkg-config --cflags --libs gtkmm-2.4`
6 | LV2 = `pkg-config --cflags --libs lv2-plugin`
7 | LV2_GUI = `pkg-config --cflags --libs lv2-gui`
8 | FAUST = -I/usr/local/lib/faust/
9 | TESTS = gen/saw.cpp gen/saw2.cpp gen/sin.cpp gen/sin2.cpp gen/square.cpp gen/square2.cpp gen/tri.cpp gen/tri2.cpp
10 |
11 | #CFLAGS=-O3 -mtune=native -march=native -mfpmath=sse -ffast-math -ftree-vectorize
12 | CFLAGS=-mtune=native -march=native -mfpmath=sse -ffast-math -ftree-vectorize
13 |
14 | $(BUNDLE): manifest.ttl analogue.ttl Analogue.so AnalogueGUI.so
15 | rm -rf $(BUNDLE)
16 | mkdir $(BUNDLE)
17 | cp $^ $(BUNDLE)
18 |
19 | Analogue.so: src/analogue.cpp gen gen/analogue.peg gen/analogue-meta.h gen/dsp.cpp
20 | g++ -shared -Wall -fPIC -DPIC src/analogue.cpp src/dsp.cpp $(LV2) $(FAUST) $(CFLAGS) -Igen/ -lm -o Analogue.so
21 |
22 | AnalogueGUI.so: src/analogue-gui.cpp gen gen/analogue.peg gen/analogue-meta.h
23 | g++ -shared -Wall -fPIC -DPIC src/analogue-gui.cpp $(GTKMM) $(LV2) $(LV2_GUI) $(CFLAGS) -Igen/ -o AnalogueGUI.so
24 |
25 | guitest: src/analogue-gui.cpp gen/analogue.peg gen/analogue-meta.h
26 | g++ -Wall src/analogue-gui-test.cpp $(GTKMM) $(LV2) $(CFLAGS) -Igen/ -o guitest.out
27 |
28 | knobtest:
29 | g++ -Wall src/knob-test.cpp $(GTKMM) $(LV2) $(CFLAGS) -Igen/ -o knobtest.out
30 |
31 | comboboxestest:
32 | g++ -Wall src/comboboxes-test.cpp $(GTKMM) $(LV2) $(CFLAGS) -Igen/ -o comboboxestest.out
33 |
34 | gen:
35 | mkdir gen
36 |
37 | gen/dsp.cpp: gen
38 | faust -fun -vec -a minimal.cpp faust/analogue-poly.dsp > gen/dsp.cpp
39 |
40 | gen/analogue.peg: gen
41 | lv2peg analogue.ttl gen/analogue.peg
42 |
43 | gen/analogue-meta.h: gen
44 | python portmeta.py
45 |
46 | standalone:
47 | faust -fun -vec -a alsa-gtk.cpp faust/standalone.dsp > gen/standalone.cpp
48 | g++ -Wall gen/standalone.cpp $(ALSA_GTK) $(FAUST) $(CFLAGS) -lm -o standalone.out
49 |
50 | poly:
51 | faust -sch -fun -vec -a alsa-gtk.cpp faust/standalone-poly.dsp > gen/standalone-poly.cpp
52 | g++ -Wall gen/standalone-poly.cpp $(ALSA_GTK) $(FAUST) $(CFLAGS) -lm -o standalone-poly.out
53 |
54 | oscdemo:
55 | faust -fun -vec -a alsa-gtk.cpp faust/oscdemo.dsp > gen/oscdemo.cpp
56 | g++ -Wall gen/oscdemo.cpp $(ALSA_GTK) $(FAUST) $(CFLAGS) -lm -o oscdemo.out
57 |
58 | simple:
59 | faust -fun -vec -a alsa-gtk.cpp faust/simple.dsp > gen/simple.cpp
60 | g++ -Wall gen/simple.cpp $(ALSA_GTK) $(FAUST) $(CFLAGS) -lm -o simple.out
61 |
62 | test2:
63 | faust -fun -vec -a alsa-gtk.cpp faust/test2.dsp > gen/test2.cpp
64 | g++ -Wall gen/test2.cpp $(ALSA_GTK) $(FAUST) $(CFLAGS) -lm -o test2.out
65 |
66 | gen/%.cpp: test/%-test.dsp
67 | faust -a minimal.cpp -cn $(patsubst gen/%.cpp,%,$@)dsp $< > $@
68 |
69 | tests: $(TESTS)
70 | g++ -Wall -fpermissive test/tests.cpp $(FAUST) -lm -Igen/ -Isrc/ -lsndfile -o tests.out
71 | ./tests.out
72 |
73 | dumpports: gen/dsp.cpp
74 | g++ -Wall src/printttl.cpp src/dsp.cpp $(PAQ) $(FAUST) -lm -lsndfile -o dumpports.out
75 | ./dumpports.out > gen/ports.ttl
76 |
77 | svg:
78 | faust -svg faust/analogue.dsp
79 | faust -svg faust/analogue-poly.dsp
80 | faust -svg faust/oscdemo.dsp
81 | faust -svg faust/standalone.dsp
82 | faust -svg faust/simple.dsp
83 |
84 | install: $(BUNDLE)
85 | mkdir -p $(INSTALL_DIR)
86 | rm -rf $(INSTALL_DIR)/$(BUNDLE)
87 | cp -R $(BUNDLE) $(INSTALL_DIR)
88 |
89 | clean:
90 | rm -rf $(BUNDLE) *.so *.out gen/* faust/*-svg
91 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Analogue synth by Timo Westkämper
2 |
3 | 2 * LFO
4 | 2 * OSC
5 | 1 * Noise
6 | 2 * FILTER (incl ENV)
7 | 2 * AMP (incl ENV)
8 |
9 | CONTENT
10 |
11 | analogue.dsp - main DSP script
12 | amps.dsp - amplifier definitions
13 | filters.dsp - filter definitions
14 | midi.dsp - MIDI controls
15 | oscillators.dsp - oscillators
16 | utils.dsp - various utilities
17 |
18 | simple.dsp - simple version for testing
19 | standalone.dsp - standalone version
20 | oscdemo.dsp - standalone oscillator
21 |
22 | DEPENDENCIES
23 |
24 | * FAUST 2.*
25 | * lv2-c++-tools
26 | * GTK 3.*
27 | * GTKMM 3.*
28 | * ALSA (for standalone code)
29 |
--------------------------------------------------------------------------------
/analogue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timowest/analogue/a9b0bd4c5d7b4473f898dcf70c21fcb0e08f7f43/analogue.png
--------------------------------------------------------------------------------
/analogue.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | zynjacku http://www.westkamper.com/lv2/analogue
3 |
--------------------------------------------------------------------------------
/analogue.ttl:
--------------------------------------------------------------------------------
1 | @prefix lv2: .
2 | @prefix doap: .
3 | @prefix foaf: .
4 | @prefix rdf: .
5 | @prefix rdfs: .
6 | @prefix ll: .
7 | @prefix pg: .
8 | @prefix ev: .
9 | @prefix ui: .
10 |
11 | @prefix ext: .
12 |
13 |
14 | a ui:GtkUI;
15 | ui:binary ;
16 | ui:requiredFeature ui:makeResident;
17 | ui:optionalFeature ui:Event.
18 |
19 | a pg:StereoGroup.
20 |
21 |
22 | a lv2:Plugin, lv2:InstrumentPlugin;
23 | lv2:binary ;
24 | doap:name "analogue";
25 | doap:maintainer [
26 | a foaf:Person;
27 | foaf:name "Timo Westkämper"
28 | ];
29 | doap:license ;
30 | ll:pegName "p";
31 | ui:ui ;
32 |
33 | lv2:port [
34 | a ev:EventPort, lv2:InputPort;
35 | lv2:index 0;
36 | ev:supportsEvent ;
37 | lv2:symbol "midi";
38 | lv2:name "MIDI";
39 | ],
40 |
41 | [
42 | a lv2:AudioPort, lv2:OutputPort;
43 | lv2:index 1;
44 | lv2:symbol "audio_l";
45 | lv2:name "Left";
46 | pg:membership [
47 | pg:group ;
48 | pg:role pg:leftChannel;
49 | ];
50 | ],
51 |
52 | [
53 | a lv2:AudioPort, lv2:OutputPort;
54 | lv2:index 2;
55 | lv2:symbol "audio_r";
56 | lv2:name "Right";
57 | pg:membership [
58 | pg:group ;
59 | pg:role pg:rightChannel;
60 | ];
61 | ],
62 |
63 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 3; lv2:symbol "amp_output"; lv2:name "output";
64 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
65 |
66 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 4; lv2:symbol "amp1_attack"; lv2:name "attack";
67 | lv2:minimum 0.000000; lv2:maximum 2.000000; lv2:default 0.000000; ext:step 0.005000 ],
68 |
69 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 5; lv2:symbol "amp1_decay"; lv2:name "decay";
70 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
71 |
72 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 6; lv2:symbol "amp1_env_to_pan"; lv2:name "env_to_pan";
73 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
74 |
75 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 7; lv2:symbol "amp1_kbd_to_level"; lv2:name "kbd_to_level";
76 | lv2:minimum -0.100000; lv2:maximum 0.100000; lv2:default 0.000000; ext:step 0.010000 ],
77 |
78 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 8; lv2:symbol "amp1_kbd_to_pan"; lv2:name "kbd_to_pan";
79 | lv2:minimum -0.100000; lv2:maximum 0.100000; lv2:default 0.000000; ext:step 0.010000 ],
80 |
81 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 9; lv2:symbol "amp1_level"; lv2:name "level";
82 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
83 |
84 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 10; lv2:symbol "amp1_lfo_to_level"; lv2:name "lfo_to_level";
85 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
86 |
87 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 11; lv2:symbol "amp1_lfo_to_pan"; lv2:name "lfo_to_pan";
88 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
89 |
90 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 12; lv2:symbol "amp1_pan"; lv2:name "pan";
91 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
92 |
93 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 13; lv2:symbol "amp1_power"; lv2:name "power";
94 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
95 |
96 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 14; lv2:symbol "amp1_release"; lv2:name "release";
97 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
98 |
99 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 15; lv2:symbol "amp1_sustain"; lv2:name "sustain";
100 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
101 |
102 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 16; lv2:symbol "amp2_attack"; lv2:name "attack";
103 | lv2:minimum 0.000000; lv2:maximum 2.000000; lv2:default 0.000000; ext:step 0.005000 ],
104 |
105 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 17; lv2:symbol "amp2_decay"; lv2:name "decay";
106 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
107 |
108 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 18; lv2:symbol "amp2_env_to_pan"; lv2:name "env_to_pan";
109 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
110 |
111 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 19; lv2:symbol "amp2_kbd_to_level"; lv2:name "kbd_to_level";
112 | lv2:minimum -0.100000; lv2:maximum 0.100000; lv2:default 0.000000; ext:step 0.010000 ],
113 |
114 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 20; lv2:symbol "amp2_kbd_to_pan"; lv2:name "kbd_to_pan";
115 | lv2:minimum -0.100000; lv2:maximum 0.100000; lv2:default 0.000000; ext:step 0.010000 ],
116 |
117 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 21; lv2:symbol "amp2_level"; lv2:name "level";
118 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
119 |
120 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 22; lv2:symbol "amp2_lfo_to_level"; lv2:name "lfo_to_level";
121 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
122 |
123 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 23; lv2:symbol "amp2_lfo_to_pan"; lv2:name "lfo_to_pan";
124 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
125 |
126 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 24; lv2:symbol "amp2_pan"; lv2:name "pan";
127 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
128 |
129 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 25; lv2:symbol "amp2_power"; lv2:name "power";
130 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
131 |
132 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 26; lv2:symbol "amp2_release"; lv2:name "release";
133 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
134 |
135 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 27; lv2:symbol "amp2_sustain"; lv2:name "sustain";
136 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
137 |
138 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 28; lv2:symbol "effects_delay_bypass"; lv2:name "bypass";
139 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
140 |
141 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 29; lv2:symbol "effects_delay_cutoff"; lv2:name "cutoff";
142 | lv2:minimum 0.000000; lv2:maximum 10000.000000; lv2:default 200.000000; ext:step 10.000000 ],
143 |
144 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 30; lv2:symbol "effects_delay_depth"; lv2:name "depth";
145 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
146 |
147 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 31; lv2:symbol "effects_delay_length"; lv2:name "length";
148 | lv2:minimum 0.000000; lv2:maximum 1000.000000; lv2:default 10.000000; ext:step 1.000000 ],
149 |
150 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 32; lv2:symbol "effects_delay_mix"; lv2:name "mix";
151 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
152 |
153 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 33; lv2:symbol "effects_flanger_bypass"; lv2:name "bypass";
154 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
155 |
156 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 34; lv2:symbol "effects_flanger_feedback"; lv2:name "feedback";
157 | lv2:minimum -0.999000; lv2:maximum 0.999000; lv2:default 0.000000; ext:step 0.001000 ],
158 |
159 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 35; lv2:symbol "effects_flanger_flange_delay"; lv2:name "flange_delay";
160 | lv2:minimum 0.000000; lv2:maximum 20.000000; lv2:default 10.000000; ext:step 0.001000 ],
161 |
162 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 36; lv2:symbol "effects_flanger_invert"; lv2:name "invert";
163 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
164 |
165 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 37; lv2:symbol "effects_flanger_mix"; lv2:name "mix";
166 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
167 |
168 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 38; lv2:symbol "effects_flanger_speed"; lv2:name "speed";
169 | lv2:minimum 0.000000; lv2:maximum 10.000000; lv2:default 0.500000; ext:step 0.010000 ],
170 |
171 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 39; lv2:symbol "effects_reverb_bypass"; lv2:name "bypass";
172 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
173 |
174 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 40; lv2:symbol "effects_reverb_damp"; lv2:name "damp";
175 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.720000; ext:step 0.025000 ],
176 |
177 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 41; lv2:symbol "effects_reverb_mix"; lv2:name "mix";
178 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.141000; ext:step 0.025000 ],
179 |
180 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 42; lv2:symbol "effects_reverb_roomSize"; lv2:name "roomSize";
181 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.540000; ext:step 0.025000 ],
182 |
183 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 43; lv2:symbol "filter1_attack"; lv2:name "attack";
184 | lv2:minimum 0.000000; lv2:maximum 2.000000; lv2:default 0.000000; ext:step 0.005000 ],
185 |
186 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 44; lv2:symbol "filter1_bypass"; lv2:name "bypass";
187 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
188 |
189 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 45; lv2:symbol "filter1_cutoff"; lv2:name "cutoff";
190 | lv2:minimum 0.000000; lv2:maximum 5000.000000; lv2:default 440.000000; ext:step 10.000000 ],
191 |
192 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 46; lv2:symbol "filter1_decay"; lv2:name "decay";
193 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
194 |
195 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 47; lv2:symbol "filter1_env_to_f"; lv2:name "env_to_f";
196 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
197 |
198 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 48; lv2:symbol "filter1_env_to_q"; lv2:name "env_to_q";
199 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.100000 ],
200 |
201 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 49; lv2:symbol "filter1_kbd"; lv2:name "kbd";
202 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 1.000000; ext:step 0.100000 ],
203 |
204 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 50; lv2:symbol "filter1_lfo_to_f"; lv2:name "lfo_to_f";
205 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
206 |
207 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 51; lv2:symbol "filter1_lfo_to_q"; lv2:name "lfo_to_q";
208 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.100000 ],
209 |
210 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 52; lv2:symbol "filter1_q"; lv2:name "q";
211 | lv2:minimum 0.000000; lv2:maximum 10.000000; lv2:default 0.500000; ext:step 0.010000 ],
212 |
213 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 53; lv2:symbol "filter1_release"; lv2:name "release";
214 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
215 |
216 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 54; lv2:symbol "filter1_sustain"; lv2:name "sustain";
217 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
218 |
219 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 55; lv2:symbol "filter1_to_f2"; lv2:name "to_f2";
220 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
221 |
222 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 56; lv2:symbol "filter1_type"; lv2:name "type";
223 | lv2:minimum 0.000000; lv2:maximum 3.000000; lv2:default 0.000000; ext:step 1.000000 ],
224 |
225 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 57; lv2:symbol "filter2_attack"; lv2:name "attack";
226 | lv2:minimum 0.000000; lv2:maximum 2.000000; lv2:default 0.000000; ext:step 0.005000 ],
227 |
228 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 58; lv2:symbol "filter2_bypass"; lv2:name "bypass";
229 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
230 |
231 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 59; lv2:symbol "filter2_cutoff"; lv2:name "cutoff";
232 | lv2:minimum 0.000000; lv2:maximum 5000.000000; lv2:default 440.000000; ext:step 10.000000 ],
233 |
234 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 60; lv2:symbol "filter2_decay"; lv2:name "decay";
235 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
236 |
237 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 61; lv2:symbol "filter2_env_to_f"; lv2:name "env_to_f";
238 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
239 |
240 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 62; lv2:symbol "filter2_env_to_q"; lv2:name "env_to_q";
241 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.100000 ],
242 |
243 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 63; lv2:symbol "filter2_kbd"; lv2:name "kbd";
244 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 1.000000; ext:step 0.100000 ],
245 |
246 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 64; lv2:symbol "filter2_lfo_to_f"; lv2:name "lfo_to_f";
247 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
248 |
249 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 65; lv2:symbol "filter2_lfo_to_q"; lv2:name "lfo_to_q";
250 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.100000 ],
251 |
252 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 66; lv2:symbol "filter2_q"; lv2:name "q";
253 | lv2:minimum 0.000000; lv2:maximum 10.000000; lv2:default 0.500000; ext:step 0.010000 ],
254 |
255 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 67; lv2:symbol "filter2_release"; lv2:name "release";
256 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 1.000000; ext:step 0.010000 ],
257 |
258 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 68; lv2:symbol "filter2_sustain"; lv2:name "sustain";
259 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 1.000000; ext:step 0.010000 ],
260 |
261 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 69; lv2:symbol "filter2_type"; lv2:name "type";
262 | lv2:minimum 0.000000; lv2:maximum 3.000000; lv2:default 0.000000; ext:step 1.000000 ],
263 |
264 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 70; lv2:symbol "lfo1_delay"; lv2:name "delay";
265 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
266 |
267 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 71; lv2:symbol "lfo1_fade_in"; lv2:name "fade_in";
268 | lv2:minimum 0.000000; lv2:maximum 5.000000; lv2:default 0.000000; ext:step 0.010000 ],
269 |
270 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 72; lv2:symbol "lfo1_freq"; lv2:name "freq";
271 | lv2:minimum 1.000000; lv2:maximum 50.000000; lv2:default 1.000000; ext:step 1.000000 ],
272 |
273 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 73; lv2:symbol "lfo1_power"; lv2:name "power";
274 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
275 |
276 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 74; lv2:symbol "lfo1_type"; lv2:name "type";
277 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 0.000000; ext:step 1.000000 ],
278 |
279 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 75; lv2:symbol "lfo1_width"; lv2:name "width";
280 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
281 |
282 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 76; lv2:symbol "lfo2_delay"; lv2:name "delay";
283 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
284 |
285 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 77; lv2:symbol "lfo2_fade_in"; lv2:name "fade_in";
286 | lv2:minimum 0.000000; lv2:maximum 5.000000; lv2:default 0.000000; ext:step 0.010000 ],
287 |
288 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 78; lv2:symbol "lfo2_freq"; lv2:name "freq";
289 | lv2:minimum 1.000000; lv2:maximum 50.000000; lv2:default 1.000000; ext:step 1.000000 ],
290 |
291 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 79; lv2:symbol "lfo2_power"; lv2:name "power";
292 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
293 |
294 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 80; lv2:symbol "lfo2_type"; lv2:name "type";
295 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 0.000000; ext:step 1.000000 ],
296 |
297 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 81; lv2:symbol "lfo2_width"; lv2:name "width";
298 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
299 |
300 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 82; lv2:symbol "noise_color"; lv2:name "color";
301 | lv2:minimum 200.000000; lv2:maximum 5000.000000; lv2:default 2000.000000; ext:step 50.000000 ],
302 |
303 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 83; lv2:symbol "noise_f1_to_f2"; lv2:name "f1_to_f2";
304 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
305 |
306 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 84; lv2:symbol "noise_level"; lv2:name "level";
307 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
308 |
309 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 85; lv2:symbol "noise_power"; lv2:name "power";
310 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
311 |
312 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 86; lv2:symbol "osc1_f1_to_f2"; lv2:name "f1_to_f2";
313 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
314 |
315 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 87; lv2:symbol "osc1_finetune"; lv2:name "finetune";
316 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
317 |
318 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 88; lv2:symbol "osc1_kbd"; lv2:name "kbd";
319 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 1.000000; ext:step 0.100000 ],
320 |
321 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 89; lv2:symbol "osc1_level"; lv2:name "level";
322 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
323 |
324 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 90; lv2:symbol "osc1_lfo_to_p"; lv2:name "lfo_to_p";
325 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
326 |
327 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 91; lv2:symbol "osc1_lfo_to_w"; lv2:name "lfo_to_w";
328 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
329 |
330 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 92; lv2:symbol "osc1_power"; lv2:name "power";
331 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
332 |
333 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 93; lv2:symbol "osc1_tune"; lv2:name "tune";
334 | lv2:minimum -24.000000; lv2:maximum 24.000000; lv2:default 0.000000; ext:step 1.000000 ],
335 |
336 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 94; lv2:symbol "osc1_type"; lv2:name "type";
337 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 0.000000; ext:step 1.000000 ],
338 |
339 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 95; lv2:symbol "osc1_width"; lv2:name "width";
340 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
341 |
342 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 96; lv2:symbol "osc2_f1_to_f2"; lv2:name "f1_to_f2";
343 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
344 |
345 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 97; lv2:symbol "osc2_finetune"; lv2:name "finetune";
346 | lv2:minimum -1.000000; lv2:maximum 1.000000; lv2:default 0.000000; ext:step 0.010000 ],
347 |
348 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 98; lv2:symbol "osc2_kbd"; lv2:name "kbd";
349 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 1.000000; ext:step 0.100000 ],
350 |
351 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 99; lv2:symbol "osc2_level"; lv2:name "level";
352 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ],
353 |
354 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 100; lv2:symbol "osc2_lfo_to_p"; lv2:name "lfo_to_p";
355 | lv2:minimum -12.000000; lv2:maximum 12.000000; lv2:default 0.000000; ext:step 0.100000 ],
356 |
357 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 101; lv2:symbol "osc2_lfo_to_w"; lv2:name "lfo_to_w";
358 | lv2:minimum -0.500000; lv2:maximum 0.500000; lv2:default 0.000000; ext:step 0.010000 ],
359 |
360 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 102; lv2:symbol "osc2_power"; lv2:name "power";
361 | lv2:minimum 0.000000; lv2:maximum 0.000000; lv2:default 1.000000; ext:step 1.000000 ],
362 |
363 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 103; lv2:symbol "osc2_tune"; lv2:name "tune";
364 | lv2:minimum -24.000000; lv2:maximum 24.000000; lv2:default 0.000000; ext:step 1.000000 ],
365 |
366 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 104; lv2:symbol "osc2_type"; lv2:name "type";
367 | lv2:minimum 0.000000; lv2:maximum 4.000000; lv2:default 0.000000; ext:step 1.000000 ],
368 |
369 | [ a lv2:ControlPort, lv2:InputPort; lv2:index 105; lv2:symbol "osc2_width"; lv2:name "width";
370 | lv2:minimum 0.000000; lv2:maximum 1.000000; lv2:default 0.500000; ext:step 0.010000 ].
371 |
372 |
--------------------------------------------------------------------------------
/analogue.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/timowest/analogue/a9b0bd4c5d7b4473f898dcf70c21fcb0e08f7f43/analogue.xcf
--------------------------------------------------------------------------------
/faust/amps.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("music.lib");
16 |
17 | import("utils.dsp");
18 |
19 | // amplifiers
20 |
21 | // in : gate, gain, pitch, lfo
22 | amp1 = vgroup("amp1", multiselect(2, checkbox("power"), 0, 0, amp));
23 |
24 | // in : gate, gain, pitch, lfo
25 | amp2 = vgroup("amp2", multiselect(2, checkbox("power"), 0, 0, amp));
26 |
27 | amp(gate, gain, pitch, lfo) = ((gate : env), _) <: (_,!,level*_*_) : amp_stereo(pitch, lfo)
28 | with {
29 | level = main_level + (kbd_to_level * (pitch - A4)) + (lfo_to_level * lfo) : (_*gain) : normalize(0,1);
30 | kbd_to_level = hslider("kbd_to_level", 0, -0.1, 0.1, 0.01) * 0.1;
31 | lfo_to_level = hslider("lfo_to_level", 0, -0.5, 0.5, 0.01);
32 | //gain_to_level = hslider("gain_to_level", 1, 0, 1, 0.01);
33 | main_level = hslider("level", 1, 0, 1, 0.01);
34 | };
35 |
36 | amp_stereo(pitch, lfo, env) = to_stereo(0.5 * (pan+1))
37 | with {
38 | pan = main_pan + (kbd_to_pan * (pitch - A4)) + (lfo_to_pan * lfo) + (env_to_pan * env) : normalize(-1,1);
39 | main_pan = hslider("pan", 0, -1, 1, 0.01);
40 | kbd_to_pan = hslider("kbd_to_pan", 0, -0.1, 0.1, 0.01) * 0.1;
41 | lfo_to_pan = hslider("lfo_to_pan", 0, -0.5, 0.5, 0.01);
42 | env_to_pan = hslider("env_to_pan", 0, -0.5, 0.5, 0.01);
43 | };
44 |
45 | to_stereo(pan) = _ <: (1-pan)*_, pan*_;
46 |
47 |
--------------------------------------------------------------------------------
/faust/analogue-poly.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | analogue = library("analogue.dsp");
16 | import("effects.dsp");
17 |
18 | // Polyphonic Analogue Synth
19 |
20 | // TODO : render only active voices
21 | voice(i) = analogue.voice(gate(i), gain(i), pitch(i))
22 | with {
23 | gate(i) = button("/h:midi/gate%i");
24 | gain(i) = nentry("/h:midi/gain%i", 0, 0, 1, 0.01);
25 | pitch(i) = hslider("/h:midi/pitch%i", 64, 32, 100, 1);
26 | };
27 |
28 | main_out = nentry("/h:amp/output", 1, 0, 1, 0.01); // TODO in dB
29 |
30 | // TODO : effects
31 | process = par(i, 8, voice(i)) :> (_,_,_,_) : effects :> (main_out * _, main_out * _);
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/faust/analogue.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("music.lib");
16 |
17 | import("midi.dsp");
18 | filters = library("filters.dsp");
19 | oscillators = library("oscillators.dsp");
20 | amps = library("amps.dsp");
21 |
22 | import("effects.dsp");
23 | import("utils.dsp");
24 |
25 | // Analogue Synth
26 |
27 | voice(gate, gain, pitch) = (lfo1, lfo2) <: (_,_,osc1,osc2,noisegen)
28 | : (_,_,pre_filter_mix) // l1, l2, f1_in, f2_in
29 | // to filters
30 | <: ((_,_,!,_), ((_,!,_,!) : filter1)) // l1, l2, f2_in, filter1, filter1_to_f2
31 | <: ((_,!,!,_,!), (!,_,!,!,!), ((!,_,_,!,_) : (_,_+_) : filter2)) // l1, f1_out, l2, f2_out
32 | // to amps
33 | : (amp1, amp2)
34 | with {
35 | lfo1 = oscillators.lfo1(gate);
36 | lfo2 = oscillators.lfo2(gate);
37 | osc1 = oscillators.osc1(pitch);
38 | osc2 = oscillators.osc2(pitch);
39 | noisegen = oscillators.noisegen;
40 | filter1 = filters.filter1(gate, pitch);
41 | filter2 = filters.filter2(gate, pitch);
42 | amp1 = amps.amp1(gate, gain, pitch);
43 | amp2 = amps.amp2(gate, gain, pitch);
44 |
45 | // in : o11, o12, o21, o22, n1, n2
46 | // out : f1_in, f2_in
47 | pre_filter_mix = bus6 <: (((_,!,_,!,_,!) : _+_+_), ((!,_,!,_,!,_) : _+_+_));
48 |
49 | };
50 |
51 | main_out = nentry("/h:amp/output", 1, 0, 1, 0.01); // TODO in dB
52 |
53 | process = voice(mono_gate, mono_gain, mono_pitch) : effects :> (main_out * _, main_out * _);
54 |
55 |
--------------------------------------------------------------------------------
/faust/dynamic.dsp:
--------------------------------------------------------------------------------
1 |
2 |
3 | process = select2(_, 0, 1);
4 |
--------------------------------------------------------------------------------
/faust/effects.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("effect.lib");
16 | import("oscillator.lib");
17 | import("music.lib");
18 | import("filter.lib");
19 | import("freeverb.dsp");
20 |
21 | import("utils.dsp");
22 |
23 | // chorus & flanger
24 |
25 | flanger_effect = vgroup("flanger", bypass2(bp, bus2 <: (bus2, flanger_stereo(dmax,curdel1,curdel2,depth,fb,invert)) : mix2_stereo(mix)))
26 | with {
27 | // parameters
28 | bp = checkbox("bypass");
29 | invert = checkbox("invert");
30 | freq = hslider("speed", 0.5, 0, 10, 0.01); // Hz
31 | depth = 1.0;
32 | //depth = hslider("depth", 1, 0, 1, 0.001);
33 | fb = hslider("feedback", 0, -0.999, 0.999, 0.01);
34 | //level = hslider("output_level", 0, -60, 10, 0.1) : db2linear; // dB
35 | mix = hslider("mix", 0.5, 0, 1, 0.01);
36 |
37 | dmax = 2048;
38 | dflange = 0.001 * SR * hslider("flange_delay", 10, 0, 20, 0.01); // ms
39 | //odflange = 0.001 * SR * hslider("delay_offset", 1, 0, 20, 0.001); // ms
40 | odflange = 0.0;
41 | curdel1 = odflange + dflange * (1 + oscrs(freq))/2; // sine for left
42 | curdel2 = odflange + dflange * (1 + oscrc(freq))/2; // cosine for right
43 | };
44 |
45 | //delay
46 |
47 | delay_effect = vgroup("delay", bypass2(bp, bus2 <: (bus2, stereo_delay) : mix2_stereo(mix)))
48 | with {
49 | bp = checkbox("bypass");
50 | length = 0.001 * SR * hslider("length", 10, 0, 1000, 1); // ms
51 | cutoff = hslider("cutoff", 200, 0, 10000, 10);
52 | depth = hslider("depth", 0.5, 0, 1, 0.01);
53 | lp_delay = lowpass(2,cutoff) : delay(SR,length);
54 | stereo_delay = bus2 : (((depth*_,depth*_,_,_) :> bus2) ~ (lp_delay, lp_delay));
55 | mix = hslider("mix", 0.5, 0, 1, 0.01);
56 | };
57 |
58 | // reverb
59 |
60 | // freeverb based
61 | reverb_effect = vgroup("reverb", bypass2(bp, fxctrl(fixedgain, mix, stereoReverb(combfeed, allpassfeed, dampSlider, stereospread))))
62 | with {
63 | bp = checkbox("bypass");
64 | dampSlider = hslider("damp",0.720, 0, 1, 0.025) * scaledamp;
65 | roomsizeSlider = hslider("roomSize", 0.540, 0, 1, 0.025) * scaleroom + offsetroom;
66 | combfeed = roomsizeSlider;
67 | mix = hslider("mix", 0.141, 0, 1, 0.025);
68 | };
69 |
70 |
71 | // topologies
72 | // A - B - C
73 | // B - A - C
74 | // A/B - C
75 | // B/A - C
76 |
77 | effects = vgroup("effects", bus4 :> bus2 : flanger_effect : delay_effect : reverb_effect);
78 |
79 |
80 |
--------------------------------------------------------------------------------
/faust/filters.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 | import("effect.lib");
15 |
16 | import("filter.lib");
17 |
18 | import("utils.dsp");
19 |
20 | // filters
21 |
22 | // in : lfo, signal
23 | filter1(gate, pitch) = vgroup("filter1", (_,(gate : env),_) : filter(pitch) <: (_, to_f2 * _) )
24 | with {
25 | to_f2 = hslider("to_f2",0,0,1,0.01);
26 | };
27 |
28 | // in : lfo, signal
29 | filter2(gate, pitch) = vgroup("filter2", (_,(gate : env),_) : filter(pitch) );
30 |
31 | filter(pitch, lfo, env) = bypass1(checkbox("bypass"), reson_filter(
32 | type,
33 | key2hz(cutoff, kbd_track * (pitch - A4) + (lfo_to_f * lfo) + (env_to_f * env)),
34 | q + (lfo_to_q * lfo) + (env_to_q * env)))
35 | with {
36 | type = hslider("type", 0, 0, 3, 1);
37 | cutoff = hslider("cutoff", 440, 0, 5000, 10);
38 | kbd_track = hslider("kbd", 1, -12, 12, 0.1);
39 | lfo_to_f = hslider("lfo_to_f",0,-12,12,0.1);
40 | env_to_f = hslider("env_to_f",0,-12,12,0.1);
41 | q = hslider("q",0.5,0,10,0.01);
42 | lfo_to_q = hslider("lfo_to_q",0,-1,1,0.1);
43 | env_to_q = hslider("env_to_q",0,-1,1,0.1);
44 | };
45 |
46 | // helpers
47 |
48 | reson_filter(type, freq, res) = _ <: select4(type,
49 | resonlp(freq, res, 1.0), // lowpass
50 | resonhp(freq, res, 1.0), // highpass
51 | resonbp(freq, res, 1.0), // bandpass
52 | resonbr(freq, res, 1.0)) // bandreject
53 | with {
54 |
55 | resonbr(fc,Q,gain,x) = (gain * x) - resonbp(fc,Q,gain,x);
56 |
57 | };
58 |
59 |
--------------------------------------------------------------------------------
/faust/freeverb.dsp:
--------------------------------------------------------------------------------
1 | declare name "freeverb";
2 | declare version "1.0";
3 | declare author "Grame";
4 | declare license "BSD";
5 | declare copyright "(c)GRAME 2006";
6 |
7 | //======================================================
8 | //
9 | // Freeverb
10 | // Faster version using fixed delays (20% gain)
11 | //
12 | //======================================================
13 |
14 |
15 | // Constant Parameters
16 | //--------------------
17 |
18 | fixedgain = 0.015;
19 | scalewet = 3.0;
20 | scaledry = 2.0;
21 | scaledamp = 0.4;
22 | scaleroom = 0.28;
23 | offsetroom = 0.7;
24 | initialroom = 0.5;
25 | initialdamp = 0.5;
26 | initialwet = 1.0/scalewet;
27 | initialdry = 0;
28 | initialwidth= 1.0;
29 | initialmode = 0.0;
30 | freezemode = 0.5;
31 | stereospread= 23;
32 | allpassfeed = 0.5;
33 |
34 |
35 | // Filter Parametres
36 | //------------------
37 |
38 | combtuningL1 = 1116;
39 | combtuningL2 = 1188;
40 | combtuningL3 = 1277;
41 | combtuningL4 = 1356;
42 | combtuningL5 = 1422;
43 | combtuningL6 = 1491;
44 | combtuningL7 = 1557;
45 | combtuningL8 = 1617;
46 |
47 | allpasstuningL1 = 556;
48 | allpasstuningL2 = 441;
49 | allpasstuningL3 = 341;
50 | allpasstuningL4 = 225;
51 |
52 |
53 | // Control Sliders
54 | //--------------------
55 | // Damp : filtrage des aigus des echos (surtout actif pour des grandes valeurs de RoomSize)
56 | // RoomSize : taille de la piece
57 | // Dry : signal original
58 | // Wet : signal avec reverbration
59 |
60 | dampSlider = hslider("Damp",0.720, 0, 1, 0.025)*scaledamp;
61 | roomsizeSlider = hslider("RoomSize", 0.540, 0, 1, 0.025)*scaleroom + offsetroom;
62 | wetSlider = hslider("Wet", 0.141, 0, 1, 0.025);
63 | drySlider = hslider("Dry", 0, 0, 1, 0.025);
64 | combfeed = roomsizeSlider;
65 |
66 |
67 |
68 |
69 |
70 | // Comb and Allpass filters
71 | //-------------------------
72 |
73 | allpass(dt,fb) = (_,_ <: (*(fb),_:+:@(dt)), -) ~ _ : (!,_);
74 |
75 | comb(dt, fb, damp) = (+:@(dt)) ~ (*(1-damp) : (+ ~ *(damp)) : *(fb));
76 |
77 |
78 | // Reverb components
79 | //------------------
80 |
81 | monoReverb(fb1, fb2, damp, spread)
82 | = _ <: comb(combtuningL1+spread, fb1, damp),
83 | comb(combtuningL2+spread, fb1, damp),
84 | comb(combtuningL3+spread, fb1, damp),
85 | comb(combtuningL4+spread, fb1, damp),
86 | comb(combtuningL5+spread, fb1, damp),
87 | comb(combtuningL6+spread, fb1, damp),
88 | comb(combtuningL7+spread, fb1, damp),
89 | comb(combtuningL8+spread, fb1, damp)
90 | +>
91 | allpass (allpasstuningL1+spread, fb2)
92 | : allpass (allpasstuningL2+spread, fb2)
93 | : allpass (allpasstuningL3+spread, fb2)
94 | : allpass (allpasstuningL4+spread, fb2)
95 | ;
96 |
97 | stereoReverb(fb1, fb2, damp, spread)
98 | = + <: monoReverb(fb1, fb2, damp, 0), monoReverb(fb1, fb2, damp, spread);
99 |
100 |
101 | // fxctrl : add an input gain and a wet-dry control to a stereo FX
102 | //----------------------------------------------------------------
103 |
104 | fxctrl(g,w,Fx) = _,_ <: (*(g),*(g) : Fx : *(w),*(w)), *(1-w), *(1-w) +> _,_;
105 |
106 |
107 |
108 | // Freeverb
109 | //---------
110 |
111 | freeverb = vgroup("Freeverb", fxctrl(fixedgain, wetSlider, stereoReverb(combfeed, allpassfeed, dampSlider, stereospread)));
112 |
113 | //process = freeverb;
114 |
--------------------------------------------------------------------------------
/faust/midi.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | // MIDI
16 |
17 | mono_pitch = hslider("/h:midi/pitch", 64, 32, 100, 1);
18 |
19 | mono_gain = hslider("/h:midi/gain", 1, 0, 1, 0.01);
20 |
21 | mono_gate = button("/h:midi/gate");
22 |
23 |
24 |
--------------------------------------------------------------------------------
/faust/oscdemo.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("midi.dsp");
16 | filters = library("filters.dsp");
17 | oscillators = library("oscillators.dsp");
18 | amps = library("amps.dsp");
19 |
20 | import("utils.dsp");
21 |
22 | // Simplified version for testing
23 |
24 | // process
25 |
26 | process = hgroup("simple", lfo1 : osc1 : (_+_))
27 | with {
28 | lfo1 = oscillators.lfo1(mono_gate);
29 | osc1 = oscillators.osc1(mono_pitch);
30 | };
31 |
32 |
33 |
--------------------------------------------------------------------------------
/faust/oscillators.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("oscillator.lib");
16 | import("music.lib");
17 |
18 | import("midi.dsp");
19 | import("utils.dsp");
20 |
21 | // oscillators
22 |
23 | // in : gate
24 | lfo1 = vgroup("lfo1", select2(checkbox("power"), 0, lfo));
25 |
26 | // in : gate
27 | lfo2 = vgroup("lfo2", select2(checkbox("power"), 0, lfo));
28 |
29 | lfo(gate) = oscillator(type, freq, width) : fade_in(fade_in_samples, gate) : delay(SR, delay_in_samples)
30 | with {
31 | type = hslider("type", 0, 0, 4, 1);
32 | freq = hslider("freq", 1, 1, 50, 1);
33 | width = hslider("width", 0.5, 0.0, 1.0, 0.01);
34 | fade_in_samples = hslider("fade_in", 0, 0, 5, 0.01) * SR;
35 | delay_in_samples = hslider("delay", 0, 0, 1, 0.01) * SR;
36 | };
37 |
38 |
39 | // in : pitch, lfo
40 | osc1 = vgroup("osc1", multiselect(2, checkbox("power"), 0, 0, osc_));
41 |
42 | // in : pitch, lfo
43 | osc2 = vgroup("osc2", multiselect(2, checkbox("power"), 0, 0, osc_));
44 |
45 | osc_(pitch, lfo) = oscillator(
46 | type,
47 | key2hz(440.0, kbd_track * (pitch - A4) + tune + finetune + (lfo_to_p * lfo)),
48 | width + lfo_to_w * lfo : normalize(0,1)) * level
49 | : split(f1_to_f2)
50 | with {
51 | type = hslider("type", 0, 0, 4, 1);
52 | kbd_track = hslider("kbd", 1, -12, 12, 0.1);
53 | tune = hslider("tune", 0, -24, 24, 1);
54 | finetune = hslider("finetune", 0, -1, 1, 0.01);
55 | lfo_to_p = hslider("lfo_to_p", 0, -12, 12, 0.1);
56 | width = hslider("width", 0.5, 0.0, 1.0, 0.01);
57 | lfo_to_w = hslider("lfo_to_w", 0, -0.5, 0.5, 0.01);
58 | level = hslider("level", 0.5, 0, 1, 0.01);
59 | f1_to_f2 = hslider("f1_to_f2", 0, 0, 1, 0.01);
60 | };
61 |
62 | // noise
63 |
64 | noisegen = vgroup("noise", multiselect(2, checkbox("power"), 0, 0, noise
65 | : lowpass(1, noise_color) * noise_level
66 | : split(f1_to_f2)))
67 | with {
68 | noise_color = hslider("color", 2000, 200, 5000, 50);
69 | noise_level = hslider("level", 0, 0, 1, 0.01);
70 | f1_to_f2 = hslider("f1_to_f2", 0, 0, 1, 0.01);
71 | };
72 |
73 | // helpers
74 |
75 | oscillator(type, freq, width) = select5(type,
76 | osc(freq),
77 | triangle(freq),
78 | sawtooth(freq),
79 | squarewave(freq, width),
80 | random)
81 | with {
82 |
83 | squarewave(freq, width) = 2 * pulsetrainpos(freq, width) - 1;
84 |
85 | triangle(freq) = saw1(freq) : abs : (_*2-1);
86 |
87 | random = noise; // TODO : improve
88 |
89 | };
90 |
91 | //process = osc1(0) : (gate * gain*_, gate * gain*_);
92 |
93 |
--------------------------------------------------------------------------------
/faust/simple.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | import("midi.dsp");
16 | filters = library("filters.dsp");
17 | oscillators = library("oscillators.dsp");
18 | amps = library("amps.dsp");
19 | import("utils.dsp");
20 |
21 | // Simplified version for testing
22 |
23 | // process
24 |
25 | // LFO > OSC > FILTER > AMP
26 | process = hgroup("simple", lfo1 <: (_,osc1) : (_,_+_) <: (_,!,filter1) : (_,_,!) : amp1)
27 | with {
28 | lfo1 = oscillators.lfo1(mono_gate);
29 | osc1 = oscillators.osc1(mono_pitch);
30 | filter1 = filters.filter1(mono_gate, mono_pitch);
31 | amp1 = amps.amp1(mono_gate, mono_gain, mono_pitch);
32 | };
33 |
34 |
--------------------------------------------------------------------------------
/faust/standalone-poly.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | analogue = library("analogue-poly.dsp");
16 |
17 | // process
18 |
19 | process = hgroup("analogue", analogue.process);
20 |
--------------------------------------------------------------------------------
/faust/standalone.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | analogue = library("analogue.dsp");
16 |
17 | // process
18 |
19 | process = hgroup("analogue", analogue.process);
20 |
--------------------------------------------------------------------------------
/faust/test.dsp:
--------------------------------------------------------------------------------
1 | //import("effect.lib");
2 | import("filter.lib");
3 | import("utils.dsp");
4 | import("math.lib");
5 |
6 | // FILTERS
7 |
8 | // reference
9 | moog_vcf(res,fr) = (+ : seq(i,4,pole(p)) : *(unitygain(p))) ~ *(mk)
10 | with {
11 | p = 1.0 - fr * 2.0 * PI / SR; // good approximation for fr << SR
12 | unitygain(p) = pow(1.0-p,4.0); // one-pole unity-gain scaling
13 | mk = -4.0 * max(0,min(res,0.999999)); // need mk > -4 for stability
14 | };
15 |
16 | // by Victor Lazzarini
17 | moogladder(f,res) = filter(f,res) : aver
18 | with {
19 | v2 = 40000;
20 | fcor(f) = 1.8730*(f^3) + 0.4955*(f^2) - 0.6490*f + 0.9988;
21 | acor(f) = -3.9364*(f^2) + 1.8409*f + 0.9968;
22 | vg2(f) = v2*(1 - exp(-2*PI*fcor(f/(SR/2))*f/(SR)));
23 | sec(f) = (/(v2) : tanh : *(vg2(f))) : + ~ (_ <: _, (/(v2) : tanh : *(vg2(f)) : *(-1)): + );
24 | filter(f,res) = (+ : sec(f) : sec(f) : sec(f) : sec(f)) ~ (*(4*res*acor(f/(SR/2))) :*(-1));
25 | aver(x) = 0.5*(x + x');
26 | };
27 |
28 | // Moog Ladder Filter
29 | //
30 | // Reference : New Approaches to Digital Subtractive Synthesis
31 | // Antti Huovilainen and Vesa Välimäki
32 | reson_filter(type, freq, res, dist_amount, drive) = filter : mix
33 | with {
34 |
35 | filter(x) = (x+_ <: (lp,_) <: (lp,!,_,_) <: (lp,!,!,_,_,_) <: (lp,!,!,!,_,_,_,_)) ~ (distort : ((_-comp*x)*mk));
36 | comp = 0.5;
37 | lp = (_*1.3) : zero(-0.3) : (_*g) : pole(1-g);
38 | g = 1.0 - exp(-2.0 * PI * freq / SR);
39 | mk = -4.0 * max(0, min(res,0.999999)); // need mk > -4 for stability
40 |
41 | distort = _ <: mix2(dist_amount, _, tanh(drive * _));
42 |
43 | mix(db0, db6, db12, db18, db24) = select8(type, db24, db18, db12, db6,
44 | db0 - db24, // hp
45 | db24 - db12, // bp12
46 | db18 - db24, // bp18/6
47 | (db18 - db24) + 2/3*db0); // notch
48 |
49 | };
50 |
51 | // Moog Ladder Filter
52 | // Digital Sound Generation - Beat Frei
53 |
54 | process = reson_filter(0, 440, 1, 0, 0, 0.5);
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/faust/test2.dsp:
--------------------------------------------------------------------------------
1 | //
2 | import("math.lib");
3 | osclib = library("oscillator.lib");
4 | import("utils.dsp");
5 |
6 | process = mix2(mix, oscillator_old(type, freq, width), dpw_oscillator(type, freq, width)) : (gain*_) <: (_,_)
7 | with {
8 | mix = hslider("mix", 0.5, 0, 1, 0.1);
9 | type = hslider("type", 0, 0, 4, 1);
10 | freq = hslider("freq", 440, 10, 10000, 10);
11 | width = hslider("width", 0.5, 0.0, 1.0, 0.1);
12 | gain = hslider("gain", 0.5, 0, 1, 0.1);
13 | };
14 |
15 | // OLD
16 |
17 | oscillator_old(type, freq, width) = select5(type,
18 | osclib.osc(freq),
19 | triangle(freq),
20 | osclib.saw1(freq),
21 | squarewave(freq, width),
22 | random)
23 | with {
24 |
25 | squarewave(freq, width) = 2.0 * osclib.pulsetrainpos(freq, width) - 1.0;
26 |
27 | triangle(freq) = osclib.saw1(freq) : abs : (_*2.0-1.0);
28 |
29 | random = osclib.noise; // TODO : improve
30 |
31 | };
32 |
33 | // DPW
34 |
35 | // saw2(freq) = saw1(freq) <: * <: -(mem) : *(0.25'*SR/freq);
36 |
37 | dpw_oscillator(type, freq, width) = phase(freq) <: select2(type > 0, sin(2*PI*_), dpw)
38 | with {
39 |
40 | dpw = bi : shape <: -(mem) : scale : (SR/freq'*_);
41 |
42 | // type tri saw square
43 | shape(x) = select3(type-1, x-x*abs(x), x*x, 0);
44 | scale = select3(type-1, 0.5, 0.25, 1)*_;
45 |
46 | };
47 |
48 | // PHASE SHAPING OSCILLATORS
49 |
50 | oscillator(type, freq, width) = phase(freq) : phase_to_osc(type, width);
51 |
52 | oscillator_slave(type, freq, width, a1) = phase(freq) : (a1*_) : mod1 : phase_to_osc(type, width);
53 |
54 | phase(freq) = (+(q) : mod1) ~ _
55 | with {
56 | q = float(freq)/float(SR);
57 | };
58 |
59 | // oscillators should be stateless : no recursion, no delays
60 | phase_to_osc(type, width) = _ <: select5(type,
61 | sin(2*PI*_), // TODO : optimize
62 | tri,
63 | saw,
64 | square(width),
65 | osclib.noise);
66 |
67 | // square (pwm)
68 | square(w) = select2(_ < w, -1.0, 1.0);
69 |
70 | saw = bi;
71 |
72 | tri = bi : fabs : bi;
73 |
74 | // PHASE SHAPERS
75 |
76 | // triangle
77 |
78 | gtri(a0, a1) = bi : fabs : glin(a0, a1) : mod1;
79 |
80 | gpulse(freq, w, x) = x - mod1(x + SR/freq) + w;
81 |
82 | // TODO
83 | //gvtri(w, a0, a1) = svtri(m) : glin(a0, a1) : mod1;
84 |
85 | gripple(m) = _ <: (_ + fmod(_,m));
86 |
87 | mod1 = fmod(_, 1.0);
88 |
89 | glin(a0, a1) = a1*_ + a0;
90 |
91 | // unipolar to bipolar
92 | bi = 2.0*_ - 1.0;
93 |
94 | // bipolar to unipolar
95 | uni = 0.5*_ + 0.5;
96 |
--------------------------------------------------------------------------------
/faust/utils.dsp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Timo Westkämper
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 2 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | */
14 |
15 | music = library("music.lib");
16 |
17 | // utilities
18 |
19 | split(ratio) = _ <: ((1-ratio) * _, ratio * _);
20 |
21 | // mix variant of select2
22 | mix2(ratio, a, b) = ratio * b + (1 - ratio) * a;
23 |
24 | mix2_stereo(ratio, al, ar, bl, br) = mix2(ratio, al, bl), mix2(ratio, ar, br);
25 |
26 | multiselect(n,s) = interleave(n,2) <: par(i,n, select2(s));
27 |
28 | select4(i,a,b,c,d) = select2(i > 2, select3(i,a,b,c), d);
29 |
30 | select5(i,a,b,c,d,e) = select2(i > 3, select4(i,a,b,c,d), e);
31 |
32 | select6(i,a,b,c,d,e,f) = select2(i > 2, select3(i,a,b,c), select3(i-2,d,e,f));
33 |
34 | select7(i,a,b,c,d,e,f,g) = select2(i > 3, select4(i,a,b,c,d), select3(i-3,e,f,g));
35 |
36 | select8(i,a,b,c,d,e,f,g,h) = select2(i > 3, select4(i,a,b,c,d), select4(i-3,e,f,g,h));
37 |
38 | fade_in(samples, gate) = select2(samples > 0, gate, fade(gate) ~ _) * _
39 | with {
40 | fade(gate, x) = select2(x < 1, gate, x + (1/samples));
41 | };
42 |
43 | normalize(min_val,max_val) = max(min_val) : min(max_val);
44 |
45 | bpm = nentry("/h:main/bpm", 120, 40, 280, 1);
46 |
47 | A4 = 69.0; // 440 Hz
48 |
49 | key2hz(base_freq, x) = base_freq * pow(2.0, x / 12);
50 |
51 | env = music.adsr(
52 | hslider("attack", 0, 0, 2, 0.005),
53 | hslider("decay", 1, 0, 4, 0.01),
54 | hslider("sustain", 1, 0, 1, 0.01) * 100,
55 | hslider("release", 1, 0, 4, 0.01));
56 |
57 |
--------------------------------------------------------------------------------
/manifest.ttl:
--------------------------------------------------------------------------------
1 | @prefix lv2: .
2 | @prefix rdfs: .
3 |
4 | a lv2:Plugin;
5 | rdfs:seeAlso .
6 |
--------------------------------------------------------------------------------
/portmeta.py:
--------------------------------------------------------------------------------
1 | import rdflib
2 | from rdflib.Graph import Graph
3 |
4 | # TODO : improve namespace usage
5 | rdf_type = rdflib.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type')
6 | lv2_ControlPort = rdflib.URIRef('http://lv2plug.in/ns/lv2core#ControlPort')
7 | lv2_index = rdflib.URIRef('http://lv2plug.in/ns/lv2core#index')
8 | lv2_symbol = rdflib.URIRef('http://lv2plug.in/ns/lv2core#symbol')
9 | lv2_name = rdflib.URIRef('http://lv2plug.in/ns/lv2core#name')
10 | lv2_minimum = rdflib.URIRef('http://lv2plug.in/ns/lv2core#minimum')
11 | lv2_maximum = rdflib.URIRef('http://lv2plug.in/ns/lv2core#maximum')
12 | lv2_default = rdflib.URIRef('http://lv2plug.in/ns/lv2core#default')
13 |
14 | ext_step = rdflib.URIRef('http://www.westkamper.com/lv2/ext#step')
15 |
16 | meta_cpp = []
17 | meta_cpp.append("#ifndef ANALOGUE_META")
18 | meta_cpp.append("#define ANALOGUE_META\n")
19 |
20 | meta_cpp.append("typedef struct {")
21 | meta_cpp.append(" const char *symbol;")
22 | meta_cpp.append(" const char *name;")
23 | meta_cpp.append(" float min;")
24 | meta_cpp.append(" float max;")
25 | meta_cpp.append(" float default_value;")
26 | meta_cpp.append(" float step;")
27 | meta_cpp.append("} port_meta_t;\n")
28 |
29 | meta_cpp.append("static const port_meta_t p_port_meta[] = {")
30 |
31 | g = Graph()
32 | g.parse("analogue.ttl", format="n3")
33 | maxIndex = 0
34 |
35 | for i in g.objects(None, lv2_index):
36 | maxIndex = max(maxIndex, i.toPython())
37 |
38 | for i in range(3, maxIndex + 1):
39 | p = g.subjects(lv2_index, rdflib.Literal(i)).next()
40 | symbol = g.objects(p, lv2_symbol).next()
41 | name = g.objects(p, lv2_name).next()
42 | minimum = g.objects(p, lv2_minimum).next().toPython()
43 | maximum = g.objects(p, lv2_maximum).next().toPython()
44 | default = g.objects(p, lv2_default).next().toPython()
45 | step = g.objects(p, ext_step).next().toPython()
46 |
47 | meta_cpp.append(' {"%s", "%s", %s, %s, %s, %s},' % (symbol, name, minimum, maximum, default, step))
48 |
49 | meta_cpp.append("};")
50 | meta_cpp.append("#endif")
51 |
52 | cppFile = open("gen/analogue-meta.h", "w")
53 | cppFile.write("\n".join(meta_cpp))
54 | cppFile.close()
55 |
56 |
--------------------------------------------------------------------------------
/src/analogue-common.h:
--------------------------------------------------------------------------------
1 | #ifndef ANALOGUE_COMMON_H
2 | #define ANALOGUE_COMMON_H
3 |
4 | #define NOUTS 2 //number of outputs
5 | #define NVOICES 8 //max polyphony
6 | #define SILENCE 0.0001f //voice choking
7 | #define CONTROL_PORT_OFFSET 3 //number of non-control ports
8 |
9 | static float scale_midi_to_f(unsigned char data) {
10 | return 0.0078f * (float)data;
11 | }
12 |
13 | static float scale_pitchbend_to_f(unsigned char data1, unsigned char data2) {
14 | return 0.000121153f * (float)(data1 * 128 + data2 - 8254);
15 | }
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/src/analogue-gui-test.cpp:
--------------------------------------------------------------------------------
1 | #include "analogue-gui.cpp"
2 | #include
3 |
4 | int main(int argc, char* argv[]) {
5 | Gtk::Main kit(argc, argv);
6 |
7 | AnalogueGUI guiBox("http://www.westkamper.com/lv2/analogue/gui");
8 |
9 | float controls[p_n_ports-3];
10 | for (int i = 0; i < p_n_ports-3; i++) {
11 | controls[i] = p_port_meta[i].default_value;
12 | }
13 |
14 | Gtk::Window window;
15 | window.set_title("Analogue");
16 | window.set_default_size(800, 400);
17 | window.add(guiBox);
18 | window.show_all();
19 |
20 | Gtk::Main::run(window);
21 |
22 | return 0;
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/analogue-gui.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "comboboxes.h"
5 | #include "knob.h"
6 | #include "toggle.h"
7 | #include "panel.h"
8 | #include "analogue.peg"
9 | #include "analogue-meta.h"
10 |
11 | #include
12 | #include
13 |
14 | using namespace sigc;
15 | using namespace Gtk;
16 |
17 | class AnalogueGUI : public LV2::GUI, LV2::WriteMIDI > {
18 | public:
19 |
20 | AnalogueGUI(const std::string& URI) {
21 | std::cout << "starting GUI" <set_size(30);
40 | knob->set_radius(10);
41 | } else if (isModControl(i) || isEffect(i)) {
42 | // medium
43 | knob->set_radius(12.0);
44 | }
45 | scales[i] = manage(knob);
46 | }
47 | }
48 |
49 | //connect widgets to control ports (change control values when sliders are moved)
50 | for (int i = 0; i < control_ports; i++) {
51 | slot slot1 = compose(bind<0>(mem_fun(*this, &AnalogueGUI::write_control), i + 3),
52 | mem_fun(*scales[i], &Changeable::get_value));
53 | slot slot2 = compose(bind<0>(mem_fun(*this, &AnalogueGUI::change_status_bar), i + 3),
54 | mem_fun(*scales[i], &Changeable::get_value));
55 | scales[i]->connect(slot1);
56 | if (!isOSCType(i) && !isFilterType(i) && !isToggle(i)) {
57 | scales[i]->connect(slot2);
58 | }
59 | }
60 |
61 | //connect all faders to the 'notify' function to inform the plugin to recalculate
62 | /*for (int i = 0; i < control_ports; i++) {
63 | scales[i]->signal_value_changed().connect(
64 | mem_fun(*this, &AnalogueGUI::notify_param_change));
65 | }*/
66 |
67 | Table* block1 = manage(new Table(2,4));
68 | block1->attach(*createOSC1(), 0, 1, 1, 2);
69 | block1->attach(*createFilter1(), 1, 2, 1, 2);
70 | block1->attach(*createAmp1(), 2, 3, 1, 2);
71 | block1->attach(*createLFO1(), 3, 4, 1, 2);
72 | block1->attach(*createLFO2(), 0, 1, 2, 3);
73 | block1->attach(*createOSC2(), 1, 2, 2, 3);
74 | block1->attach(*createFilter2(), 2, 3, 2, 3);
75 | block1->attach(*createAmp2(), 3, 4, 2, 3);
76 | mainBox.pack_start(*align(block1));
77 |
78 | HBox* block3 = manage(new HBox());
79 | block3->pack_start(*createFilter1Env());
80 | block3->pack_start(*createFilter2Env());
81 | block3->pack_start(*createAmp1Env());
82 | block3->pack_start(*createAmp2Env());
83 | mainBox.pack_start(*align(block3));
84 |
85 | HBox* block4 = manage(new HBox());
86 | block4->pack_start(*createNoise());
87 | block4->pack_start(*createFlanger());
88 | block4->pack_start(*createDelay());
89 | block4->pack_start(*createReverb());
90 | mainBox.pack_start(*align(block4));
91 |
92 | HBox* header = manage(new HBox());
93 | header->pack_start(*manage(new Image("analogue.png")));
94 | header->pack_end(*scales[p_amp_output - 3]->get_widget());
95 | header->set_border_width(5);
96 | mainBox.pack_start(*align(header));
97 |
98 | mainBox.pack_end(statusbar);
99 |
100 | add(*align(&mainBox));
101 |
102 | std::cout << "GUI ready" <attach(*scales[port_index - 3]->get_widget(), left, left + 1, top, top + 1);
297 | table->attach(*manage(new Label(label)), left, left + 1, top + 1, top + 2);
298 | }
299 |
300 | Widget* smallFrame(const char* label, Table* content) {
301 | content->set_border_width(2);
302 | content->set_col_spacings(2);
303 | content->set_spacings(2);
304 |
305 | Frame* frame = manage(new Frame());
306 | frame->set_label_align(0.0f, 0.0f);
307 | frame->set_border_width(5);
308 | frame->set_label(label);
309 | frame->add(*content);
310 |
311 | Alignment* alignment = manage(new Alignment(0.0, 0.0, 1.0, 0.0));
312 | alignment->add(*frame);
313 | return alignment;
314 | }
315 |
316 | Widget* frame(const char* label, int toggle, Table* content) {
317 | content->set_border_width(2);
318 | content->set_col_spacings(5);
319 | content->set_spacings(2);
320 |
321 | Panel* panel = manage(new Panel(label, scales[toggle - 3]->get_widget(), content));
322 |
323 | Alignment* alignment = manage(new Alignment(0.0, 0.0, 1.0, 0.0));
324 | alignment->add(*panel);
325 | return alignment;
326 | }
327 |
328 | Alignment* align(Widget* widget) {
329 | Alignment* alignment = manage(new Alignment(0.0, 0.0, 0.0, 0.0));
330 | alignment->add(*widget);
331 | return alignment;
332 | }
333 |
334 | bool isEffect(int i) {
335 | const char* symbol = p_port_meta[i].symbol;
336 | return strstr(symbol, "effects_");
337 | }
338 |
339 | bool isToggle(int i) {
340 | const char* symbol = p_port_meta[i].symbol;
341 | return strstr(symbol, "_power") || strstr(symbol, "_bypass");
342 | }
343 |
344 | bool isPower(int i) {
345 | const char* symbol = p_port_meta[i].symbol;
346 | return strstr(symbol, "_power");
347 | }
348 |
349 | bool isBypass(int i) {
350 | const char* symbol = p_port_meta[i].symbol;
351 | return strstr(symbol, "_bypass");
352 | }
353 |
354 | bool isOSCType(int i) {
355 | const char* symbol = p_port_meta[i].symbol;
356 | return (strstr(symbol, "osc") || strstr(symbol, "lfo")) && strstr(symbol, "_type");
357 | }
358 |
359 | bool isFilterType(int i) {
360 | const char* symbol = p_port_meta[i].symbol;
361 | return strstr(symbol, "filter1_type") || strstr(symbol, "filter2_type");
362 | }
363 |
364 | bool isEnvControl(int i) {
365 | const char* symbol = p_port_meta[i].symbol;
366 | return strstr(symbol, "_attack") || strstr(symbol, "_decay") || strstr(symbol, "_sustain") || strstr(symbol, "_release");
367 | }
368 |
369 | bool isModControl(int i) {
370 | const char* symbol = p_port_meta[i].symbol;
371 | return strstr(symbol, "_kbd_") || strstr(symbol, "_lfo_") || strstr(symbol, "_env_");
372 | }
373 |
374 | void port_event(uint32_t port, uint32_t buffer_size, uint32_t format, const void* buffer) {
375 | if (port > 2) {
376 | scales[port-3]->set_value(*static_cast(buffer));
377 | }
378 | }
379 |
380 | void change_status_bar(uint32_t port, float value) {
381 | if (p_port_meta[port-3].step >= 1.0f) {
382 | sprintf(statusBarText, "%s = %3.0f", p_port_meta[port-3].symbol, value);
383 | } else {
384 | sprintf(statusBarText, "%s = %3.3f", p_port_meta[port-3].symbol, value);
385 | }
386 | statusbar.remove_all_messages();
387 | statusbar.push(statusBarText);
388 | }
389 |
390 | protected:
391 | VBox mainBox;
392 | Statusbar statusbar;
393 | char statusBarText[100];
394 |
395 | //Knob *scales[p_n_ports - 3];
396 | Changeable *scales[p_n_ports - 3];
397 | };
398 |
399 | static int _ = AnalogueGUI::register_class("http://www.westkamper.com/lv2/analogue/gui");
400 |
401 |
--------------------------------------------------------------------------------
/src/analogue.cpp:
--------------------------------------------------------------------------------
1 | #include "analogue.h"
2 | #include
3 | #include
4 |
5 | Analogue::Analogue(double r) : LV2::Plugin >(p_n_ports) {
6 | //license notice
7 | std::cout << std::endl;
8 | std::cout << "Analogue v.0.1, Copyright (c) 2011 Timo Westkämper" << std::endl;
9 | std::cout << "This is free software, and you are welcome to redistribute it" << std::endl;
10 | std::cout << "under certain conditions; see LICENSE file for details." << std::endl;
11 | std::cout << std::endl;
12 |
13 | // TODO : presets
14 |
15 | rate = r;
16 | m_midi_input = 0;
17 | m_midi_type = Parent::uri_to_id(LV2_EVENT_URI, "http://lv2plug.in/ns/ext/midi#MidiEvent");
18 |
19 | synthUI = new CollectorUI();
20 | synthUI->setOutputs(outputs);
21 |
22 | synth = createDSP();
23 | synth->init((int)r);
24 | synth->buildUserInterface(synthUI);
25 |
26 | // zones for MIDI data
27 | //pitchBend = synthUI->getZone("pitchBend");
28 | //breathControl = synthUI->getZone("breathControl");
29 |
30 | char buffer[32];
31 | for (int i = 0; i < NVOICES; i++) {
32 | sprintf(buffer, "midi_pitch%d", i);
33 | pitch[i] = synthUI->getZone(buffer);
34 | sprintf(buffer, "midi_gain%d", i);
35 | gain[i] = synthUI->getZone(buffer);
36 | sprintf(buffer, "midi_gate%d", i);
37 | gate[i] = synthUI->getZone(buffer);
38 | }
39 |
40 | // zones for control ports
41 | for (int i = 0; i < p_n_ports - 3; i++) {
42 | zones[i] = synthUI->getZone(p_port_meta[i].symbol);
43 | if (zones[i] == 0) {
44 | // TODO Exception
45 | std::cout << "No zone for " << p_port_meta[i].symbol << std::endl;
46 | }
47 | }
48 |
49 | std::cout << "ready" <compute(to - from, 0, outputs);
115 | }
116 |
117 | void Analogue::run(uint32_t sample_count) {
118 | LV2_Event_Iterator iter;
119 | lv2_event_begin(&iter, p < LV2_Event_Buffer>(m_midi_input));
120 |
121 | uint8_t* event_data;
122 | uint32_t samples_done = 0;
123 |
124 | while (samples_done < sample_count) {
125 | uint32_t to = sample_count;
126 | LV2_Event* ev = 0;
127 | if (lv2_event_is_valid(&iter)) {
128 | ev = lv2_event_get(&iter, &event_data);
129 | to = ev->frames;
130 | lv2_event_increment(&iter);
131 | }
132 |
133 | if (to > samples_done) {
134 | render(samples_done, to);
135 | samples_done = to;
136 | }
137 |
138 | /* This is what we do with events:
139 | - if it's a MIDI event, pass it to handle_midi()
140 | - if it's something else, just ignore it (it's safe)
141 | */
142 | if (ev) {
143 | if (ev->type == m_midi_type) {
144 | handle_midi(ev->size, event_data);
145 | }
146 | }
147 | }
148 |
149 | }
150 |
151 | void Analogue::handle_midi(uint32_t size, unsigned char* data) {
152 | //discard invalid midi messages
153 | if (size < 2) {
154 | return;
155 | }
156 |
157 | //receive on all channels
158 | switch(data[0] & 0xf0) {
159 |
160 | //note off
161 | case 0x80: {
162 | //discard invalid midi messages
163 | if (size != 3) {
164 | return;
165 | }
166 | off(data[1], data[2]);
167 | }
168 | break;
169 |
170 | //note on
171 | case 0x90: {
172 | //discard invalid midi messages
173 | if (size != 3) {
174 | return;
175 | }
176 | on(data[1], data[2]);
177 | }
178 | break;
179 |
180 | //pitch bend
181 | case 0xE0: {
182 | //discard invalid midi messages
183 | if (size != 3) {
184 | return;
185 | }
186 |
187 | setPitchBend(scale_pitchbend_to_f(data[1], data[2]));
188 | }
189 | break;
190 |
191 | case 0xB0: //controller
192 | //WIP: control preset parameters with assigned controllers
193 | {
194 | /*signed char param_id = -1;
195 | param_id = get_param_id_from_controller(data[1]);
196 | if (param_id >= 0) {
197 | float new_value = scale_midi_to_f(data[2]);
198 | setParameter(param_id, new_value);
199 | }*/
200 | }
201 |
202 | // standard controller stuff
203 | switch(data[1])
204 | {
205 | //mod wheel
206 | case 0x01:
207 | //discard invalid midi messages
208 | if (size != 3) {
209 | return;
210 | }
211 | //scale the mod value to cover the range [0..1]
212 | // DO NOTHING
213 | std::cout << "mod " << (int)data[2] << std::endl;
214 | break;
215 |
216 | // breath
217 | case 0x02:
218 | //discard invalid midi messages
219 | if (size != 3) {
220 | return;
221 | }
222 | setBreathControl(scale_midi_to_f(data[2]));
223 | break;
224 |
225 | //volume
226 | case 0x07:
227 | //discard invalid midi messages
228 | if (size != 3) {
229 | return;
230 | }
231 |
232 | setVolumeControl(scale_midi_to_f(data[2]));
233 | break;
234 |
235 | default:
236 | // TODO
237 | break;
238 | }
239 | break;
240 |
241 | default:
242 | break;
243 | }
244 | }
245 |
246 | static int _ = Analogue::register_class(p_uri);
247 |
--------------------------------------------------------------------------------
/src/analogue.h:
--------------------------------------------------------------------------------
1 | #ifndef ANALOGUE_H
2 | #define ANALOGUE_H
3 | //See associated .cpp file for copyright and other info
4 |
5 | #include
6 | #include
7 |
8 | #include "analogue-common.h"
9 | #include "analogue.peg"
10 | #include "analogue-meta.h"
11 |
12 | #include "dsp.h"
13 | #include "collector-ui.h"
14 |
15 | class Analogue : public LV2::Plugin > {
16 | private:
17 | typedef LV2::Plugin > Parent;
18 |
19 | float rate;
20 | float *outputs[2];
21 |
22 | float* pitch[NVOICES];
23 | float* gain[NVOICES];
24 | float* gate[NVOICES];
25 | //float* pitchBend;
26 | //float* breathControl;
27 |
28 | float *zones[p_n_ports-3];
29 |
30 | dsp *synth;
31 | CollectorUI* synthUI;
32 |
33 | protected:
34 |
35 | uint32_t m_midi_input;
36 | uint32_t m_midi_type;
37 |
38 | template T*& p(uint32_t port) {
39 | return reinterpret_cast(Parent::m_ports[port]);
40 | }
41 |
42 | float*& p(uint32_t port) {
43 | return reinterpret_cast(Parent::m_ports[port]);
44 | }
45 |
46 |
47 | public:
48 | Analogue(double rate);
49 | ~Analogue();
50 |
51 | void handle_midi(uint32_t size, unsigned char* data);
52 | void setPitchBend(float value);
53 | void setBreathControl(float value);
54 | void setVolumeControl(float value);
55 | void run(uint32_t sample_count);
56 |
57 | void on(unsigned char key, unsigned char velo);
58 | void off(unsigned char key, unsigned char velo);
59 | void render(uint32_t from, uint32_t to);
60 | };
61 | #endif
62 |
--------------------------------------------------------------------------------
/src/changeable.h:
--------------------------------------------------------------------------------
1 | #ifndef CHANGEABLE_H
2 | #define CHANGEABLE_H
3 |
4 | #include
5 | #include
6 |
7 | class Changeable {
8 | public:
9 |
10 | virtual float get_value() = 0;
11 |
12 | virtual void set_value(float val) = 0;
13 |
14 | virtual void connect(sigc::slot slot) = 0;
15 |
16 | // TODO : is this necessary or should we use inheritance instance?
17 | virtual Gtk::Widget* get_widget() = 0;
18 |
19 | };
20 |
21 | #endif //CHANGEABLE_H
22 |
--------------------------------------------------------------------------------
/src/collector-ui.h:
--------------------------------------------------------------------------------
1 | #ifndef COLLECTOR_UI_H
2 | #define COLLECTOR_UI_H
3 |
4 | #include "dsp.h"
5 |
6 | #include