«Simple wrapper class for VSTPlugin» by david_morgan

on 29 Dec'19 13:41 in

This is a class to streamline some of the boilerplate code for wiring up the VSTPlugin extension. It is intended to make using VSTPlugin with a NodeProxy somewhat easier.

It's only been tested on a Mac with develop branch build of SuperCollider with PR-4499 merged.

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
///////////////////////////////
// To use:

// Install VSTPlugin
// available here: https://git.iem.at/pd/vstplugin/-/releases

// Create a NodeProxy as a sound source for testing
(
Ndef(\sine, {
	var sig = SinOsc.ar(440);
	var env = Decay2.kr(Impulse.kr(0.5));
	Splay.ar(sig) * env * 0.1;
})
)

// display discovered keys
Vst(\delay1).keys.do({arg k; k.postln;});
// load a vst by key or path
Vst(\delay1).load('/Library/Audio/Plug-Ins/VST/ValhallaDelay');
// route the test sound source to the internal node proxy
Vst(\delay1).node.source = Ndef(\sine);
// monitor the vst with fade in
Vst(\delay1).node.play(fadeTime:4);
// view the editor if enabled (see PR-4499 for mac)
Vst(\delay1).editor;
// view the default gui
Vst(\delay1).gui;
// toggle bypass: 1 or 0
Vst(\delay1).bypass(1);
// stop monitoring the vst with fade out
Vst(\delay1).node.stop(fadeTime:4);

// since the vst is output through a node proxy
// it can be further routed as a regular node proxy
(
Ndef(\fx, {
	var in = \in.ar([0, 0]);
	PitchShift.ar(in, 0.2, 2, 0.01, 0.01);
});
)
Ndef(\fx) <<> Vst(\delay1).node;
Ndef(\fx).play;


///////////////////////////////
// copy the below code to SC extensions folder
// e.g. ~/Library/Application Support/SuperCollider/Extensions
Vst {

	classvar <all;
	var <key;
	var <outergrouop, <innergroup, <vstgroup;
	var <vstctrl, <node, <synth;
	var func;

	*new {arg key;
		var res = all[key];
		if (res.isNil) {
			res = super.new.prInit(key);
			all.put(key, res);
		};
		^res;
	}

	prInit {arg inKey;
		key = inKey;
		^this;
	}

	load {arg name;

		func = {

			Routine({

				var inbus;

				SynthDef.new(key, {
					var in = \in.kr(0);
					var bypass = \bypass.kr(0);
					var sig = VSTPlugin.ar(input:In.ar(in, 2), numOut:2, bypass:bypass, id:key) * \amp.kr(1);
					ReplaceOut.ar(\in.kr(0), sig);
				}).add;

				Server.default.sync;

				outergrouop = Group.new(Server.default).debug(\outergroup);
				innergroup = Group.new(outergrouop).debug(\innergroup);

				if (node.isNil) {
					// TODO: still have to reset the source
					// after cmdperiod in order for sound to contine
					// but i'm not sure why
					"initialize nodeproxy".postln;
					node = NodeProxy.audio(Server.default, 2);
				};
				node.group_(innergroup);//.play;

				inbus = node.bus;
				vstgroup = Group.new(target:node.group.debug(\node), addAction:\addAfter);

				synth = Synth(key, [in: inbus], target:vstgroup.debug(\fx), addAction:\addToTail);
				vstctrl = VSTPluginController(synth, key);
				vstctrl.open(name, editor:true);

			}).play;
		};

		func.value;

		// TODO: is this the right way to do this?
		CmdPeriod.add(func);
	}

	bypass {arg bypass=0;
		synth.set(\bypass, bypass)
	}

	set {arg key, val;
		vstctrl.set(key, val)
	}

	map {arg key, val;
		vstctrl.map(key, val)
	}

	get {arg key, cb={arg v; v.postln;};
		vstctrl.get(key, cb);
	}

	editor {
		vstctrl.editor;
	}

	gui {
		vstctrl.gui;
	}

	keys {
		var result = List.new;
		VSTPlugin.search(verbose:false);
		VSTPlugin.readPlugins.keysValuesDo({arg k, v; result.add(k)});
		^result.asArray;
	}

	free {
		synth.free;
		vstgroup.free;
		innergroup.free;
		outergrouop.free;
		node.clear;
		CmdPeriod.remove(func);
	}

	*initClass {
		all = ();
	}
}
raw 3376 chars (focus & ctrl+a+c to copy)
reception
comments