Dynamic stochastic synthesis#

Xenakis mentions the idea of generating stochastic sound material by directly generating amplitude waves that are calculated stochastically.

We can use an EnvGen at audiorate to set levels and the time positions of these levels dynamically by other UGens, therefore allowing us to generate waves that obey the ideas of dynamic stochastic synthesis.

ADSR

Source: https://commons.wikimedia.org/wiki/File:ADSR_parameter.svg

s.boot;
-> localhost
Ndef(\dynamicStochasticSynthesis, {
	var freq = \freq.kr(150.0);

	// maybe this is just a too complicated way to
	// create a lo-res wavetable synth?
	// but at least it can do this w/ n channels

	// by increasing the steps of the env we can enrich overtones
	// how could one modulate this b/c this plays with
	// the number of channels in the ugen graph :?
	// can go up to 5000
	var steps = 100;
	var levels = steps.collect({
		// provide a function for each step of our env
		// !2 makes it stereo but could be increased beyond
		LFDNoise3.kr(1!2);
	});
	var times = steps.collect({
		// provide a function for each step of our env
		// !2 makes it stereo but could be increased beyond
		LFDNoise3.kr(1!2);
	})/steps;

	var env = EnvGen.ar(
		envelope: Env(
			levels: levels+1, // we need to offset as env seems to perform .min(0.0) on the levels
			times: times[1..],
			//times: 1/(freq*(levels.size-1)),
			// another parameter is to fluctuate the envelope times at each section
			// best is to distribute from something which sums up to 1 so its pitch is stable
			// times: (levels.size-1).collect({1/(freq*(levels.size-1))*LFDNoise1.kr(mul: 0.21)}),

			// another parameter is the steepness of each segment
			// this could be set globally for the env or for each step independently
			curve: 0.5,
			// curve: LFDNoise0.ar(1.0)*0.2, // bigger values lead to more metallic sound
		).postcs,
		gate: Impulse.ar(freq),
	)-1; // remove the offset
	0.2*SplayAz.ar(2, env);
}).play(numChannels: 2);
Env([ [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new, BinaryOpUGen.new ], [ BinaryOpUGen.new-> Ndef('dynamicStochasticSynthesis')
%% record "dynamic_syntha.flac"
-> localhost
s.stopRecording;
Ndef(\dynamicStochasticSynthesis).stop(fadeTime: 2)
Recording Stopped: (dynamic_syntha.flac)
-> Ndef('dynamicStochasticSynthesis')
Ndef(\dynamicStochasticSynthesis, {
	var sig;
	
	sig = {
		var env;
		var levels, time;
		levels = { LFDNoise1.kr(MouseX.kr(0.01, 100, 1)) } ! 20;
		time = { LFDNoise1.kr(MouseY.kr(0.05, 100, 1)).range(1/200, 1/20000) } ! 19;
		env = Env(levels, time[1..]).circle(time[0]);
		EnvGen.ar(env, timeScale:1/10) * 0.1
		
	} ! 2;
	
	sig;
}).play(numChannels: 2);
-> Ndef('dynamicStochasticSynthesis')
%% record "dynamic_synthb.flac"
-> localhost
s.stopRecording;
Ndef(\dynamicStochasticSynthesis).stop(fadeTime: 2)
Recording Stopped: (dynamic_synthb.flac)
-> Ndef('dynamicStochasticSynthesis')
Ndef(\dynamicStochasticSynthesis, {
	var sig, mx, my;
	var nLevels;
	mx = MouseX.kr(0, 1);
	my = MouseX.kr(0, 1);
	
	nLevels = 20;
	sig = {
		var env;
		var levels, time;
		levels = { LFDNoise1.kr(mx.linexp(0, 1, 0.01, 100, 1)) } ! nLevels;
		time = { LFDNoise1.kr(my.linexp(0, 1, 0.05, 100, 1)).exprange(1/100, 1/2000) } ! (nLevels - 1);
		env = Env(levels, time[1..]).circle(time[0]);
		EnvGen.ar(env, timeScale:1/10) * 0.1
		
	} ! 16;
	
	Splay.ar(sig)
	
}).play(numChannels: 2);
-> Ndef('dynamicStochasticSynthesis')
%% record "dynamic_synthc.flac"
-> localhost
s.stopRecording;
Ndef(\dynamicStochasticSynthesis).stop(fadeTime: 2)
Recording Stopped: (dynamic_synthc.flac)
-> Ndef('dynamicStochasticSynthesis')