{
   "description" : "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.\r\n\r\nIt's only been tested on a Mac with develop branch build of SuperCollider with PR-4499 merged.",
   "ancestor_list" : [],
   "name" : "Simple wrapper class for VSTPlugin",
   "author" : "david_morgan",
   "code" : "///////////////////////////////\r\n// To use:\r\n\r\n// Install VSTPlugin\r\n// available here: https://git.iem.at/pd/vstplugin/-/releases\r\n\r\n// Create a NodeProxy as a sound source for testing\r\n(\r\nNdef(\\sine, {\r\n\tvar sig = SinOsc.ar(440);\r\n\tvar env = Decay2.kr(Impulse.kr(0.5));\r\n\tSplay.ar(sig) * env * 0.1;\r\n})\r\n)\r\n\r\n// display discovered keys\r\nVst(\\delay1).keys.do({arg k; k.postln;});\r\n// load a vst by key or path\r\nVst(\\delay1).load('/Library/Audio/Plug-Ins/VST/ValhallaDelay');\r\n// route the test sound source to the internal node proxy\r\nVst(\\delay1).node.source = Ndef(\\sine);\r\n// monitor the vst with fade in\r\nVst(\\delay1).node.play(fadeTime:4);\r\n// view the editor if enabled (see PR-4499 for mac)\r\nVst(\\delay1).editor;\r\n// view the default gui\r\nVst(\\delay1).gui;\r\n// toggle bypass: 1 or 0\r\nVst(\\delay1).bypass(1);\r\n// stop monitoring the vst with fade out\r\nVst(\\delay1).node.stop(fadeTime:4);\r\n\r\n// since the vst is output through a node proxy\r\n// it can be further routed as a regular node proxy\r\n(\r\nNdef(\\fx, {\r\n\tvar in = \\in.ar([0, 0]);\r\n\tPitchShift.ar(in, 0.2, 2, 0.01, 0.01);\r\n});\r\n)\r\nNdef(\\fx) <<> Vst(\\delay1).node;\r\nNdef(\\fx).play;\r\n\r\n\r\n///////////////////////////////\r\n// copy the below code to SC extensions folder\r\n// e.g. ~/Library/Application Support/SuperCollider/Extensions\r\nVst {\r\n\r\n\tclassvar <all;\r\n\tvar <key;\r\n\tvar <outergrouop, <innergroup, <vstgroup;\r\n\tvar <vstctrl, <node, <synth;\r\n\tvar func;\r\n\r\n\t*new {arg key;\r\n\t\tvar res = all[key];\r\n\t\tif (res.isNil) {\r\n\t\t\tres = super.new.prInit(key);\r\n\t\t\tall.put(key, res);\r\n\t\t};\r\n\t\t^res;\r\n\t}\r\n\r\n\tprInit {arg inKey;\r\n\t\tkey = inKey;\r\n\t\t^this;\r\n\t}\r\n\r\n\tload {arg name;\r\n\r\n\t\tfunc = {\r\n\r\n\t\t\tRoutine({\r\n\r\n\t\t\t\tvar inbus;\r\n\r\n\t\t\t\tSynthDef.new(key, {\r\n\t\t\t\t\tvar in = \\in.kr(0);\r\n\t\t\t\t\tvar bypass = \\bypass.kr(0);\r\n\t\t\t\t\tvar sig = VSTPlugin.ar(input:In.ar(in, 2), numOut:2, bypass:bypass, id:key) * \\amp.kr(1);\r\n\t\t\t\t\tReplaceOut.ar(\\in.kr(0), sig);\r\n\t\t\t\t}).add;\r\n\r\n\t\t\t\tServer.default.sync;\r\n\r\n\t\t\t\toutergrouop = Group.new(Server.default).debug(\\outergroup);\r\n\t\t\t\tinnergroup = Group.new(outergrouop).debug(\\innergroup);\r\n\r\n\t\t\t\tif (node.isNil) {\r\n\t\t\t\t\t// TODO: still have to reset the source\r\n\t\t\t\t\t// after cmdperiod in order for sound to contine\r\n\t\t\t\t\t// but i'm not sure why\r\n\t\t\t\t\t\"initialize nodeproxy\".postln;\r\n\t\t\t\t\tnode = NodeProxy.audio(Server.default, 2);\r\n\t\t\t\t};\r\n\t\t\t\tnode.group_(innergroup);//.play;\r\n\r\n\t\t\t\tinbus = node.bus;\r\n\t\t\t\tvstgroup = Group.new(target:node.group.debug(\\node), addAction:\\addAfter);\r\n\r\n\t\t\t\tsynth = Synth(key, [in: inbus], target:vstgroup.debug(\\fx), addAction:\\addToTail);\r\n\t\t\t\tvstctrl = VSTPluginController(synth, key);\r\n\t\t\t\tvstctrl.open(name, editor:true);\r\n\r\n\t\t\t}).play;\r\n\t\t};\r\n\r\n\t\tfunc.value;\r\n\r\n\t\t// TODO: is this the right way to do this?\r\n\t\tCmdPeriod.add(func);\r\n\t}\r\n\r\n\tbypass {arg bypass=0;\r\n\t\tsynth.set(\\bypass, bypass)\r\n\t}\r\n\r\n\tset {arg key, val;\r\n\t\tvstctrl.set(key, val)\r\n\t}\r\n\r\n\tmap {arg key, val;\r\n\t\tvstctrl.map(key, val)\r\n\t}\r\n\r\n\tget {arg key, cb={arg v; v.postln;};\r\n\t\tvstctrl.get(key, cb);\r\n\t}\r\n\r\n\teditor {\r\n\t\tvstctrl.editor;\r\n\t}\r\n\r\n\tgui {\r\n\t\tvstctrl.gui;\r\n\t}\r\n\r\n\tkeys {\r\n\t\tvar result = List.new;\r\n\t\tVSTPlugin.search(verbose:false);\r\n\t\tVSTPlugin.readPlugins.keysValuesDo({arg k, v; result.add(k)});\r\n\t\t^result.asArray;\r\n\t}\r\n\r\n\tfree {\r\n\t\tsynth.free;\r\n\t\tvstgroup.free;\r\n\t\tinnergroup.free;\r\n\t\toutergrouop.free;\r\n\t\tnode.clear;\r\n\t\tCmdPeriod.remove(func);\r\n\t}\r\n\r\n\t*initClass {\r\n\t\tall = ();\r\n\t}\r\n}",
   "id" : "1-5cp",
   "is_private" : null,
   "labels" : []
}
