DynGen - Dynamic UGen

DynGen v0.3.0

This is a big update!

  • Pass parameters via name by prepending variables with _ in DynGen scripts
  • Address in- and output channels dynamically using in() and out() functions. This combined with named parameters allows to write effects such as PanAz which operate on an arbitrary number of in- and output channels but have fixed parameters (e.g. pos) for each instance
  • Proper multi-channel expansion
  • Write and read SC buffers using bufRead, bufReadL, bufReadC and bufWrite
  • Introduce @init, @block and @sample sections which allow to set init values for e.g. dynamic systems
  • Add FFT support via phase vocoder
  • Adding helper methods: clip, fold, wrap, mod, lin, cubic
  • Replacing DynGenRT by using the modulatable parameter sync in DynGen
  • Add modulatable update parameter to indicate if the running DynGen unit should listen for code updates or not
  • Add method free and freeAll to free scripts from the server

Check the docs for proper explaination of each feature.

If you are interested in some meta-programming in sclang: there is a discussion to see if DynGen scripts could be replaced with a sclang-native binding, see Add sclang transpiler · Issue #55 · capital-G/DynGen · GitHub

A big shout out to @Spacechild1 for code-reviewing and contributing!

Feedback, bug reports and nice snippets and sounds are always appreciated in this thread!

Here is a small sound snippet, feeding the output of a lorentz attractor into a complex oscillator

(
DynGenDef(\lorentz, "
@init
x=1.0;
y=1.0;
z=1.0;
oversample = 16;

@sample
loop(oversample,
  x += _dt * (_a *(y - x));
  y += _dt * ((x * (_b - z)) - y);
  z += _dt * ((x*y) - (_c*z));
);

out0 = x / 22;
out1 = y / 29;
out2 = (z - 27) / 54;
").send;

DynGenDef(\complex, "
@init
oversample = 32;
sRateOS = srate * oversample;
phaseA = 0;
phaseB = 0;

@sample

// calculate subsaples
loop(oversample,
  phaseA += _freqA / sRateOS;
  phaseB += _freqB / sRateOS;

  phaseA -= floor(phaseA);
  phaseB -= floor(phaseB);

  signalA = sin(2 * $pi * phaseA);
  signalB = sin(2 * $pi * phaseB);

  phaseA += _modIndexA * signalB;
  phaseB += _modIndexB * signalA;
);

out0 = signalA;
out1 = signalB;
").send;
)

(
Ndef(\x, {
	var lorentz = DynGen.ar(3, \lorentz, params: [
		a: \a.kr(10.0, spec: [9.0, 11.0]),
		b: \b.kr(28.0, spec: [26.0, 29.0]),
		c: \c.kr(8/3, spec: [7/3, 9/3]),
		dt: \dt.kr(0.1, spec: [0.001, 1.0, \exp]) * 0.0001,
	]);
	var modDepth = \modDepth.kr(0.01, spec: [0.0001, 0.1, \exp]);
	var sig = DynGen.ar(2, \complex, params: [
		freqA: \freqA.ar(300.0, spec: \freq) * 0.1,
		freqB: (lorentz[2].abs+0.01).exprange(0.01, 1.0, \loFreq.kr(20.0, spec: \freq), \hiFreq.kr(800.0, spec: \freq)),// \freqB.ar(200.0, spec: \freq),
		modIndexA: lorentz[0] * modDepth,
		modIndexB: lorentz[1] * modDepth,
	]);
	
	LeakDC.ar(sig) * 0.2;
}).play.gui;
)
14 Likes