«hamma» by hamma

on 02 Dec'21 12:41 in drone gui visuals graphics

a go at making something like metaphysical function from NI reaktor in SC

original instrument design by mike daliot

based on ScopeView helpfile and

https://www.youtube.com/watch?v=l-uuPlAk_FY

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
a go at making something like metaphysical function from NI reaktor in SC
original instrument design by mike daliot
based on ScopeView helpfile and
https://www.youtube.com/watch?v=l-uuPlAk_FY

how to use:
this instrument generates harsh drones and visuals.
use with caution! protect your hearing! dist goes loud!

1. add a little spin with spin t1, t2 and/or fine
2. detune one of the oscillators using tune/fine

a and b is a bank of 4 sine oscs and 2 pulse oscs with pw 0.5 and 0.2

(
var w, ctr = IdentityDictionary[], gui = IdentityDictionary[];
var syn, scopeSyn, scope, func, bus, buffer;

w = Window("Scope", Rect(0, 0, 800, 500));

ctr[\defaultfreqs] = 60 ! 6;
ctr[\defaultfine] = 0.0 ! 6;
ctr[\defaultamps] = [-12] ++ (-120 ! 5);

gui[\views] = [\topBar, \scopeView, \zoomView, \lowBar];
gui[\basicView] = { View().background_(Color.gray).layout_(HLayout()) };

gui[\views].do({ |view| gui[view] = gui[\basicView].value });

[\a, \b].do({ |ab|
	[\Top, \Mid, \Low].do({ |tier|
		gui[(ab++tier).asSymbol] = gui[\basicView].value;
	})
});

func = {
	arg view, synarg, spec, contr, defaults, i;
	var sl, values;
	sl = Slider(gui[view]).action_({
		values = ctr[contr].collect({|sl| spec.asSpec.map(sl.value)});
		syn.setn(synarg, values);
		//values.postln
	});

	sl.value_(spec.asSpec.unmap(ctr[defaults][i]))
};

// lazy labels
[StaticText(gui[\topBar]).string_("a tune  /  fine  /  amp\t\t       alvl"), View(gui[\topBar]).minWidth_(450), StaticText(gui[\topBar]).string_("blvl\t\t       b tune  /  fine  /  amp")];
[View(gui[\lowBar]).maxWidth_(163), StaticText(gui[\lowBar], Rect(200, 0, 200, 20)).string_(
"a+b                    zoom                    spin t1                    t2                       fine                        fb                       dist                       a*b")];

// the 2 groups of 3 * 6 controls for a and b
ctr[\atune] = {|i| func.(\aTop, \afreqs, [5, 125, \lin, 1 ], \atune, \defaultfreqs, i)} !6;
ctr[\btune] = {|i| func.(\bTop, \bfreqs, [5, 125, \lin, 1 ], \btune, \defaultfreqs, i)} !6;

ctr[\afine] = {|i| func.(\aMid, \afine, [-1, 1], \afine, \defaultfine, i)} !6;
ctr[\bfine] = {|i| func.(\bMid, \bfine, [-1, 1], \bfine, \defaultfine, i)} !6;

ctr[\aamp] = {|i| func.(\aLow, \aamps, [-120, -4, \exp], \aamp, \defaultamps, i)} ! 6;
ctr[\bamp] = {|i| func.(\bLow, \bamps, [-120, -4, \exp], \bamp, \defaultamps, i)} ! 6;

gui[\layout] = VLayout(
	gui[\topBar],
	HLayout(
		VLayout(
			gui[\aTop],
			gui[\aMid],
			gui[\aLow],
		),
		VLayout(
			gui[\scopeView],
			gui[\zoomView].maxHeight_(100),
		),
		VLayout(
			gui[\bTop],
			gui[\bMid],
			gui[\bLow],
		),
	),
	gui[\lowBar]
);

SynthDef("scope", {
	var sig;
	sig = In.ar(\in.kr(0), 2);
	// ScopeOut2 writes the audio to the buffer
	// IMPORTANT - ScopeOut2, not ScopeOut
	ScopeOut2.ar(sig, \bufnum.kr(0));
	Out.ar(0, sig*0.1);
}).add;

SynthDef("test3", {
	var a, b, f, sig;
	var afreqs, bfreqs, aamps, bamps;
	afreqs = \afreqs.kr(ctr[\defaultfreqs]) + \afine.kr(ctr[\defaultfine]);
	bfreqs = \bfreqs.kr(ctr[\defaultfreqs]) + \bfine.kr(ctr[\defaultfine]);

	aamps = \aamps.kr(ctr[\defaultamps]);
	bamps = \bamps.kr(ctr[\defaultamps]);

	a = SinOsc.ar(afreqs[0..3].midicps, 0.0, aamps[0..3].dbamp);
	b = SinOsc.ar(bfreqs[0..3].midicps, 0.0, bamps[0..3].dbamp);

	a = a + Pulse.ar(afreqs[4..].midicps, [0.5, 0.2], aamps[4..].dbamp);
	b = b + Pulse.ar(bfreqs[4..].midicps, [0.5, 0.2], bamps[4..].dbamp);

	sig = ((a+b) * \absum.kr(0.5)) + ((a*b) * \abmul.kr(0.5));

	sig = (sig * \dist.kr(1.0)).tanh;

	f = LocalIn.ar(2, 0);
	f = f * \fb.kr(0.0);

	a =  DelayL.ar(sig+f[0], 2, \aspin.kr(0.0, 0.1));
	b =  DelayL.ar(sig+f[1], 2, \bspin.kr(0.0, 0.1) + \finespin.kr(0.0, 0.2));

	LocalOut.ar([a, b]);

	a = a * \alvl.kr(0.5);
	b = b * \blvl.kr(0.5);

	Out.ar(\out.kr(0), [a, b]);
}).add;

// scope view with lvl controls
Slider(gui[\scopeView]).action_({|sl| syn.set(\alvl, [0.0, 1.0].asSpec.map(sl.value))}).value_(0.5);
scope = ScopeView(gui[\scopeView], Rect(0,0,380,380)); // this is SCScope
Slider(gui[\scopeView]).action_({|sl| syn.set(\blvl, [0.0, 1.0].asSpec.map(sl.value))}).value_(0.5);

// controls below scope
Knob(gui[\zoomView]).action_({|sl| syn.set(\absum, [0.0, 1.0].asSpec.map(sl.value))}).value_(0.5);

Slider(gui[\zoomView]).action_({|sl| scope.yZoom = ([0.125, 20, \exp, 1/8, 1].asSpec.map(sl.value))}).valueAction_(0.0);
Slider(gui[\zoomView]).action_({|sl| syn.set(\aspin, [0.0, 0.49].asSpec.map(sl.value))}).value_(0.0);
Slider(gui[\zoomView]).action_({|sl| syn.set(\bspin, [0.0, 0.49].asSpec.map(sl.value))}).value_(0.0);
Slider(gui[\zoomView]).action_({|sl| syn.set(\finespin, [0.0, 0.1, \lin, 0.001].asSpec.map(sl.value))}).value_(0.0);
Slider(gui[\zoomView]).action_({|sl| syn.set(\fb, [-0.2, 0.2].asSpec.map(sl.value))}).value_(0.5);
Slider(gui[\zoomView]).action_({|sl| syn.set(\dist, [1, 50].asSpec.map(sl.value))}).value_(0.0);

Knob(gui[\zoomView]).action_({|sl| syn.set(\abmul, [0.0, 1.0].asSpec.map(sl.value))}).value_(0.5);

buffer = Buffer.alloc(s, 1024,2);
bus = Bus.audio(s, 1); // why 1?

scope.bufnum = buffer.bufnum;
scope.style = 2;
​
// IMPORTANT
scope.server = s;

scopeSyn = Synth.tail(RootNode(s), "scope", [\in, bus.index, \bufnum, buffer.bufnum]);
syn = Synth("test3", [\out, bus.index]);

scope.start;

w.onClose = {
	syn.free; scopeSyn.free; buffer.free; bus.free;
	syn = scopeSyn = scope = func = buffer = bus = nil };

CmdPeriod.doOnce({w.close});
w.layout = gui[\layout];
w.front;
)
raw 5600 chars (focus & ctrl+a+c to copy)
reception
comments