class:: Ndef
summary:: node proxy definition
categories:: Libraries>JITLib>NodeProxy, Live Coding
related:: Classes/ProxySpace, Classes/Tdef

description::
Reference to a proxy, forms an alternative to link::Classes/ProxySpace::. All methods are inherited from link::Classes/NodeProxy::.

code::
Ndef(key)	//returns the instance
Ndef(key, obj)	//stores the object and returns the instance, like Tdef and Pdef.
::

Graphical editor overviewing all current Ndefs: link::Classes/NdefMixer::. A general overview: link::Overviews/JITLib::.

subsection::First Example

code::
s.boot;

Ndef(\a).play; // play to hardware output.
Ndef(\a).fadeTime = 2; // fadeTime specifies crossfade
// set the source
Ndef(\a, { SinOsc.ar([350, 351.3], 0, 0.2) });
Ndef(\a, { Pulse.ar([350, 351.3] / 4, 0.4, 0.2) });
Ndef(\a, Pbind(\dur, 0.03, \freq, Pbrown(0, 1, 0.1, inf).linexp(0, 1, 200, 350)));

Ndef(\a, { Ringz.ar(Ndef.ar(\b), [350, 351.3] * 2, 0.4) });
Ndef(\b, { Impulse.ar([5, 7]/2, [0, 0.5], 0.15) });

Ndef.clear(3); // clear all after 3 seconds
::

ClassMethods::

private::initClass

subsection::Creation

method::new
Return a new node proxy and store it in a global ProxySpace under the key. If there is already an Ndef there, replace its object with the new one. The object can be any supported class, see link::Classes/NodeProxy#Supported sources:: help.

argument::key
the name of the proxy (usually a symbol). If only the key is given and no object, it returns the proxy object:
code::
Ndef(\x) // get the proxy
::

If key is an association, it is interpreted as strong::key -> server name::. (order changed in SC3.3 !). If no name is given, it uses the default server that was default when Ndef was first called. (to change it, see link::#*defaultServer::).

argument::object
an object

code::
Ndef(\x, { Dust.ar }); // returns the proxy and set the source object.
::

method::ar
equivalent to code::*new(key).ar(numChannels, offset):: (see link::Classes/BusPlug#ar::)

method::kr
equivalent to code::*new(key).kr(numChannels, offset):: (see link::Classes/BusPlug#kr::)

method::clear
clear all proxies

method::defaultServer
set the default server (default: code::Server.default::)

method::all
Return the dictionary of all servers, pointing to proxyspaces with Ndefs for each.

code::
Ndef.all;
::

method::dictFor
Return the proxyspace for a given server.

code::
Ndef.dictFor(s);
::

subsection::Setting default parameters
Behind every Ndef there is one single instance of link::Classes/ProxySpace:: per server used (usually just the one for the default server). This ProxySpace keeps default values for the proxies that can be set. This can be done by:

code::
// set default quant
Ndef(\x).proxyspace.quant = 1.0;
::
The other values that can be set in such a way are: code::clock, fadeTime, quant, reshaping, awake::.


Examples::

code::
s.boot;

Ndef(\sound).play;
Ndef(\sound).fadeTime = 1;
Ndef(\sound, { SinOsc.ar([600, 635], 0, SinOsc.kr(2).max(0) * 0.2) });
Ndef(\sound, { SinOsc.ar([600, 635] * 3, 0, SinOsc.kr(2 * 3).max(0) * 0.2) });
Ndef(\sound, { SinOsc.ar([600, 635] * 2, 0, SinOsc.kr(2 * 3).max(0) * 0.2) });
Ndef(\sound, Pbind(\dur, 0.17, \freq, Pfunc({ rrand(300, 700) })) );

Ndef(\lfo, { LFNoise1.kr(3, 400, 800) });
Ndef(\sound).map(\freq, Ndef(\lfo));
Ndef(\sound, { arg freq; SinOsc.ar([600, 635] + freq, 0, SinOsc.kr(2 * 3).max(0) * 0.2) });
Ndef(\lfo, { LFNoise1.kr(300, 400, 800) });

Ndef.clear; //clear all Ndefs
::

subsection::using Ndef inside other Ndefs

code::
Ndef(\lfo2, { LFNoise1.kr(LFNoise1.kr(0.1).exprange(1, 300) ! 2, 400, 800) });
Ndef(\sound, { Blip.ar(Ndef.kr(\lfo2), 30) * 0.2 }).play;

Ndef(\lfo2, { [MouseX.kr(10, 300, 1), MouseY.kr(10, 300, 1)] });
::

subsection::setting and mapping parameters

code::
Ndef(\sound, { |freq = 56, numHarm = 10| Blip.ar(freq, numHarm, 30) * 0.2 }).play;
Ndef(\sound).set(\freq, 15);
Ndef(\sound).set(\freq, 15, \numHarm, 100);

Ndef(\lfo, { LFNoise2.kr(2).exprange(10, 200) });
Ndef(\sound).map(\numHarm, Ndef(\lfo));
Ndef(\sound).set(\numHarm, nil); // unmap.
Ndef(\sound).stop;
::


subsection::Simple audio routing with the <<> operator

code::
(
Ndef(\sound, {
	RHPF.ar(
		\in1.ar([0, 0]) * \in2.ar([0, 0]),
		\freq.kr(6000, 2),
		\rq.kr(0.2)
	) * 7
}).play;
Ndef(\sound).fadeTime = 0.2;	// avoid harsh clicks
)

Ndef(\a, { SinOsc.ar(MouseX.kr(300, 1000, 1) * [1, 1.2], \phase.ar([0, 0]) * 0.2) });
Ndef(\b, { LFDNoise3.ar(MouseY.kr(3, 1000, 1) * [1, 1.2]) });
Ndef(\c, { LFTri.ar(MouseY.kr(3, 10, 1) * [1, 1.2]).max(0) });
Ndef(\a).fadeTime = 0.2;	// avoid harsh clicks again

Ndef(\sound) <<>.in1 Ndef(\a);
Ndef(\sound) <<>.in2 Ndef(\b);
Ndef(\sound) <<>.in2 Ndef(\c);
Ndef(\a) <<>.phase Ndef(\sound);
Ndef(\a) <<>.phase nil;	// unmap
Ndef.clear(3);		// fade out and clear all Ndefs
::

subsection::Making Copies

method::copy
Because an Ndef is a unique instance for a given key, it can be copied only by supplying a new key.
See also: link::Classes/NodeProxy#-copy::.

code::
Ndef(\x, { SinOsc.ar(Rand(500, 900)) * 0.1 }).play;
Ndef(\x).copy(\y);
Ndef(\y).play;
::

argument::newKey
A valid new key, usually a link::Classes/Symbol::

subsection::Recursion

Ndefs can be used recursively. A structure like the following works:

code::
Ndef(\sound, { SinOsc.ar([600, 635], Ndef.ar(\sound), LFNoise1.kr(2).max(0) * 0.2) });
Ndef(\sound).play;
Ndef.clear;
::

This is because there is a feedback delay (the server's strong::block size::), usually 64 samples, so that calculation can reiterate over its own outputs. For single sample feedback, see:

code::
(Platform.resourceDir +/+ "examples/demonstrations/single_sample_feedback.scd").openDocument;
::

subsection::Using different servers

code::
// create a new server
a = Server(\foo, NetAddr("127.0.0.1", 57123)).boot.makeWindow;
Ndef(\sound, { SinOsc.ar([600, 635]) * SinOsc.kr(2).max(0) * 0.2 }).play; // play on default
Ndef(\sound -> \foo, { SinOsc.ar([700, 745]) * SinOsc.kr(2).max(0) * 0.2 }).play;// play on foo

// clear definitions
Ndef(\sound -> \foo).clear(3);
Ndef(\sound).clear(3);

a.dump;	// display settings of new server
a.quit;	// terminate new server
::
subsection::GUI

code::
// create a window for a given Ndef
Ndef(\sound).edit
(
Ndef(\sound, { |freq = 440, rate = 2|
	SinOsc.ar(freq * [1, 1.625]) * SinOsc.kr(rate).max(0) * 0.2
}).play;
)

// set lags for controls:
Ndef(\sound).lag(\freq, 0.2, \rate, 0.5);
Ndef(\sound).clear(1);

// create a mixer for all Ndefs:
NdefMixer(s);
::

subsection::Using Associations

For a complete list, see link::Classes/NodeProxy::, and link::Reference/NodeProxy_roles::

code::
// setsrc
(
Ndef(\x,
	\setsrc -> Pbind(\source,
		Pseq([
			{ LFTri.ar(280 * Line.kr(1.1, 0.4, rrand(2, 3)) + [0,1]) * 0.1 },
			{ Pulse.ar(40 + [0,1]) * 0.1 },
			{ LFTri.ar(LFTri.kr(1).round(1.0.rand) + 1 * 180 + [0,1], 0.04) * 0.3 },
		], inf),
		\dur, Prand([3, 2, 4], inf)
	)
).play;
)
::
