File: VSTPluginNodeProxyController.schelp

package info (click to toggle)
pd-vstplugin 0.6.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,008 kB
  • sloc: cpp: 22,794; lisp: 2,860; makefile: 37; sh: 26
file content (213 lines) | stat: -rw-r--r-- 6,140 bytes parent folder | download
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
TITLE:: VSTPluginNodeProxyController
summary:: VSTPluginController for JITLib
categories:: JITLib
related:: Classes/VSTPlugin

DESCRIPTION::
This class is used to control a specific link::Classes/VSTPlugin:: instance in a link::Classes/NodeProxy::, so you can
open plugins, automate parameters, change programs, send MIDI messages, etc.

Have a look at the examples at the bottom!

note::Don't use any NodeProxy crossfading methods, like link::Classes/NodeProxy#-xset::, because this would close the actual VST plugin and invalidate the corresponding controller.

(The reason is that JITLib implements crossfading by creating a new Synth on the Server and destroying the old one.)::

warning::link::Classes/NodeProxy#-<<>:: and link::Classes/NodeProxy#-<>>:: call code::xset:: internally. Use code::set(\in, ...):: instead!::

SUBSECTION:: NodeProxy roles

To use VSTPlugin in a NodeProxy, you have to use one the following link::Reference/NodeProxy_roles:::

definitionlist::
## code::\vst:: || a UGen graph function containing one or more VSTPlugin instances.
code::
Ndef(\test, \vst -> { VSTPlugin.ar(nil, 2) });
::
## code::\vstDef:: || the name of a SynthDef containing one or more VSTPlugin instances
code::
SynthDef(\vsti, { |out| Out.ar(out, VSTPlugin.ar(nil, 2)) }).add;

Ndef(\test, \vstDef -> \vsti);
::
## code::\vstFilter:: || like code::\filter:: (use the proxy`s own bus as the input)
code::
Ndef(\vst)[0] = { WhiteNoise.ar(0.1) ! 2 };
Ndef(\vst)[1] = \vstFilter -> { |in| VSTPlugin.ar(in, 2) };
::
::


CLASSMETHODS::

METHOD:: new
Create a new VSTPluginNodeProxyController for a given NodeProxy.

ARGUMENT:: proxy
the link::Classes/NodeProxy::.

ARGUMENT:: index
the source index.

ARGUMENT:: id
a Symbol which uniquely identifies the link::Classes/VSTPlugin:: in the link::Classes/SynthDef::.

note::If this is the only VSTPlugin instance in the SynthDef, the code::id:: argument can be omitted.::

ARGUMENT:: wait
the default wait time, see link::Classes/VSTPluginController#-wait::.

DISCUSSION::
Initially, no VST plugin is loaded and the UGen is automatically bypassed (i.e. the input is just passed through).


METHOD:: collect
Same as link::#-new::, but returns an link::Classes/Event:: of VSTPluginNodeProxyControllers, with their IDs used as keys.
This is useful if you have a SynthDef containing several VSTPlugin instances.

ARGUMENT:: proxy
the NodeProxy, see link::#-new::

ARGUMENT:: index
the source index

ARGUMENT:: ids
an Array of IDs referring to link::Classes/VSTPlugin:: instances in the link::Classes/SynthDef::, or code::nil:: (= collect all).

ARGUMENT:: wait
the default wait time, see link::Classes/VSTPluginController#-wait::.

DISCUSSION::
code::
(
Ndef(\vst, \vst -> {
	var sig = WhiteNoise.ar(0.1) ! 2;
	sig = VSTPlugin.ar(sig, 2, id: \fx1);
	sig = VSTPlugin.ar(sig, 2, id: \fx2);
}).play;

~fx = VSTPluginNodeProxyController.collect(Ndef(\vst));
~fx.fx1.open("GChorus", editor: true);
~fx.fx2.open("GDelay", editor: true);
)
::

PRIVATE:: initProxyAndCondition, checkIfStarted

INSTANCEMETHODS::

METHOD:: sendMsg

METHOD:: proxy

EXAMPLES::

code::
VSTPlugin.search;

// ------------
// a) Filter white noise through a VST plugin
(
Ndef(\test, \vst -> { VSTPlugin.ar(WhiteNoise.ar(0.1) ! 2, 2) }).play;

~fx = VSTPluginNodeProxyController(Ndef(\test)).open("GChorus", editor: true, action: _.set('R Phase', 0.3, \Mix, 0.5));
)

~fx.editor; // open the VST plugin editor

// automate parameters with a Pbind of type \vst_set
(
Pdef(\auto, Pbind(
	\type, \vst_set,
    \vst, ~fx, // VSTPluginNodeProxyController
	\params, [\Depth, \Freq],
	\Depth, Pwhite(0.1, 0.9),
    \Freq, Pseq([0.1, 0.2, 0.5, 0.9], inf),
	\dur, Prand([0.25, 0.5, 1], inf)
)).play;
)

Pdef(\auto).stop;
Pdef(\auto).play;

// ------------
// b) For more flexibility, let's split it into seperate sources; the first source is filtered by the second source
(
Ndef(\test)[0] = { WhiteNoise.ar(0.1) ! 2 };
Ndef(\test)[1] = \vstFilter -> { |in| VSTPlugin.ar(in, 2) };
Ndef(\test).play;

// We want to control the source at index 1!
~fx = VSTPluginNodeProxyController(Ndef(\test), 1).open("GChorus", editor: true);
)

// ------------
// c) Let's go one step further and use seperate NodeProxies
(
Ndef(\white, { WhiteNoise.ar(0.1) ! 2 });
Ndef(\fx, \vst -> { VSTPlugin.ar(\in.ar(0 ! 2), 2) });
// Route \white to \fx. (Don't use '<>>' or '<<>'!)
Ndef(\fx).set(\in, Ndef(\white));
Ndef(\fx).play;

~fx = VSTPluginNodeProxyController(Ndef(\fx)).open("GChorus", editor: true);
)

// Now it's possible to change the routing on the fly:
(
Ndef(\pink, { PinkNoise.ar(0.1) ! 2 });
Ndef(\fx).set(\in, Ndef(\pink));
)

// ------------
// d) If you look at the last example, you might notice that the VSTPlugin function will always be the same, so it makes sense to use a SynthDef instead! Most of the time the following SynthDefs should be sufficient:

(
// mono insert FX
SynthDef(\vst_fx_mono, { |out| Out.ar(out, VSTPlugin.ar(\in.ar(0), 1)) }).add;

// stereo insert FX
SynthDef(\vst_fx_stereo, { |out| Out.ar(out, VSTPlugin.ar(\in.ar(0 ! 2), 2)) }).add;

// VST instrument (stereo)
SynthDef(\vsti, { |out| Out.ar(out, VSTPlugin.ar(nil, 2)) }).add;
)

// Now let's rewrite c) by using the \vstDef role:
(
Ndef(\white, { WhiteNoise.ar(0.1) ! 2 });
Ndef(\fx, \vstDef -> \vst_fx_stereo);
// Route \white to \fx. (Don't use '<>>' or '<<>'!)
Ndef(\fx).set(\in, Ndef(\white));
Ndef(\fx).play;

~fx = VSTPluginNodeProxyController(Ndef(\fx)).open("GChorus", editor: true);
)

// ------------
// e) Creating a VST instrument is simple:
(
// This needs the \vsti SynthDef above!
Ndef(\inst, \vstDef -> \vsti).play;
~inst = VSTPluginNodeProxyController(Ndef(\inst)).open("Dexed", editor: true, action: _.program_(1));
Ndef(\inst).play;
)

~inst.editor;

// Now play some notes with a Pbind of type \vst_midi
(
Pdef(\seq, Pbind(
	\type, \vst_midi,
    \vst, ~inst,
    \midinote, Pseq(#[0, 2, 4, 7], inf) + Pwhite(-12, 12).stutter(Pwhite(4, 16)) + 60,
    \dur, Prand(#[0.125, 0.25, 0.5], inf),
    \legato, Pexprand(0.5, 1.0, inf),
    \amp, Pexprand(0.5, 1.0, inf)
)).play;
)
// Pause/resume/end the Pbind.
Pdef(\seq).stop;
Pdef(\seq).play;

::