MM – Additional – No sample WaveTable experiments.

Here are three more experiments. From simple to complex.

Three different approaches to morph wavetables.

//////////////////////////////////////////////////////////////////////////////
// Additional wavetable experiments with buffers and no external samples.
// 2020 Matias Monteagudo.
//////////////////////////////////////////////////////////////////////////////

//Interface settings. Ignore/Change at will.
(
Server.local.options.device = "ASIO : ASIO PreSonus FireStudio";
Server.local.options.sampleRate=48000;
Server.local.options.hardwareBufferSize=128;
)

Server.local.options.numBuffers=32768;//This we'll need for the last synth. Evaluate before boot.

//////////////////////////////////////////////////////////////////////////////
//Reverb. Will create a verb and refresh the node tree. Keep an eye on the Node tree window.
(
(
SynthDef(\verb, {
	|in, predelay=1, revtime=2, lpf=4500,mix=0.5,amp=1,out=0|
	var dry,wet,temp,sig;
	dry = In.ar(in, 2);
	temp = In.ar(in, 2);
	wet=0;
	temp=DelayN.ar(temp, 0.2, predelay);
	32.do {temp=AllpassN.ar(temp, 0.05, {Rand(0.001,0.05)}!2,revtime);
		temp=LPF.ar(temp,lpf);
		wet=wet+temp;
	};
	sig=XFade2.ar(dry,wet,mix*2-1,amp);
	Out.ar(out,sig);
}).add;
);

(
ServerTree.removeAll;
~revBus = Bus.audio(s,2);
~createReverb={~reverbSynth=Synth(\verb, [\mix,0.23, \in, ~revBus])};
ServerTree.add(~createReverb);
s.freeAll;
s.scope;
s.freqscope;
s.plotTree;
);
)


//////////////////////////////////////////////////////////////////////////////
//Just two wavetables and Xfade.
// Sinusoidal to a rich in harmonics waveform. Simple stuff.
// Can be expanded to have as many waveforms.
//////////////////////////////////////////////////////////////////////////////
//Waveform 1

~w1=Buffer.alloc(s, 2048, 1);

(
var env, sig, wt;
env=Env([0,0.5,0,-0.5,0],[0.2,0.2,0.2,0.2,],[-3.3333, 3.3333]);
sig=env.asSignal(1024);
wt=sig.asWavetable;
~w1.loadCollection(wt);
)

~w1.plot

//Waveform 2

~w2=Buffer.alloc(s, 2048, 1);

(
var env, sig, wt, numSegs;
numSegs=rrand(4,20);
env=Env([0,1,0,-1,0,1,0,-1,0], [0.3,0.01,0.5,1,0.01,0.7].rand,[-4,4,-4,4].rand);
sig=env.asSignal(1024);
wt=sig.asWavetable;
~w2.loadCollection(wt);
)

~w2.plot

//////////////////////////////////////////////////////////////////////////////
//Synth

(
SynthDef(\wt, {
	|freq=500, amp=0.6, atk=0.01, rel=1, pan=0,cur= 20|
	var sig,w1,w2;
	w1=Osc.ar(~w1, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	w2=Osc.ar(~w2, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	sig=XFaderN.ar([w1,w2],LFTri.ar(0.1, add:0.5),1);
	sig=LeakDC.ar(sig);
	sig=Pan2.ar(sig,pan);
	Out.ar(~revBus, sig);
}).add
)

x=Synth(\wt, [\rel, 1000]);
x.free


//////////////////////////////////////////////////////////////////////////////
//4 wavetables cycle updating (behind scenes).
//Not the best approach but it still a proof of concept.
// When it works you shouldn't hear sudden changes.
//////////////////////////////////////////////////////////////////////////////
//Waveforms 3,4,5,6
(
(
~w3=Buffer.alloc(s, 2048, 1);
~r1=Routine({
	loop({
		var env, sig, wt, numSegs;
		numSegs=rrand(4,20);
		env=Env([0,1,0,-1,0,1,0,-1,0], [0.5,0.03,0.5,1,0.01,0.7].rand,[-4,4,-4,4].rand);
		sig=env.asSignal(1024);
		wt=sig.asWavetable;
		~w3.loadCollection(wt);
		~t.wait;
	});
});
);

(
~w4=Buffer.alloc(s, 2048, 1);
~r2=Routine({
	|atTime|
	loop({
		var env, sig, wt, numSegs;
		numSegs=rrand(4,20);
		env=Env([0,1,0,-1,0,1,0,-1,0], [0.1,0.2].rand,[-4,4,-4,4].rand);
		sig=env.asSignal(1024);
		wt=sig.asWavetable;
		~w4.loadCollection(wt);
		~t.wait;
	});
});
);

(
~w5=Buffer.alloc(s, 2048, 1);
~r3=Routine({
	loop({
		var env, sig, wt, numSegs;
		numSegs=rrand(4,20);
		env=Env([0,1,0,-1,0,1,0,-1,0], [0.01,0.2,0.5,1,0.7,2].rand,[-4,0,-4,4].rand);
		sig=env.asSignal(1024);
		wt=sig.asWavetable;
		~w5.loadCollection(wt);
		~t.wait;
	});
});
);

(
~w6=Buffer.alloc(s, 2048, 1);
~r4=Routine({
	loop({
		var env, sig, wt, numSegs;
		numSegs=rrand(4,20);
		env=Env([0,1,0,-1,0,1,0,-1,0], [0.4,0.08,0.5,1,0.4,0.4].rand,0);
		sig=env.asSignal(1024);
		wt=sig.asWavetable;
		~w6.loadCollection(wt);
		~t.wait;
	});
});
);
)



//////////////////////////////////////////////////////////////////////////////
//Synth.

(
TempoClock.tempo=120/60;
~t=TempoClock.tempo;
(
~r1.play(quant: [4,3]);
~r2.play(quant: [4,4]);
~r3.play(quant: [4,5]);
~r4.play(quant: [4,6]);
);

(
x=SynthDef(\wt2, {
	|freq=100, amp=0.5, atk=0.01, rel=100, pan=0,cur= 20|
	var sig,w1,w2,w3,w4;
	w1=Osc.ar(~w3, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	w2=Osc.ar(~w4, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	w3=Osc.ar(~w5, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	w4=Osc.ar(~w6, freq,0)*EnvGen.kr(Env([0,amp,0],[atk,rel],cur),1,doneAction:2);
	sig=DXMix.ar(Dseq([0,1,2,3],inf),`[w1,w2,w3,w4],~t/4);
	sig=LeakDC.ar(sig);
	sig=Pan2.ar(sig,pan);
	Out.ar(~revBus, sig);
}).add;
);
x.play(quant: 4);
)

x.free

//////////////////////////////////////////////////////////////////////////////
//Eternally (and externally) changing wavetables using a Routine to
//generate arrays of wavetables then sent to a SynthDef and a Pbind.
//////////////////////////////////////////////////////////////////////////////
((
	~routine.stop;
	~routine=Routine{
		inf.do({
			(
				~w = 10.collect({
					var env, numSegs;
					numSegs=rrand(4,6);
					env=Env(
						({rrand(0.0,0.8)}!(numSegs+1)) * [1,-1].scramble,
						{rrand(0.4,2)}!numSegs,
						{rrand(-0.01,0.02)}!numSegs
					).asSignal(1024);
					env=env * Env([0,1,1,0],[2,3,2]).asSignal(1024); //Cycle In and out fades.
				});
				//load into 10 buffers in wavetable format
				~w = Buffer.allocConsecutive(10, s, 2048, 1, {
					arg buf, index;
					buf.setnMsg(0, ~w[index].asWavetable);
				});

				/*(
				~w[0].plot;
				~w[1].plot;
				~w[2].plot;
				~w[3].plot;
				~w[4].plot;
				~w[5].plot;
				~w[6].plot;
				~w[7].plot;
				~w[8].plot;
				~w[9].plot;
				)*/

				//Synth
				SynthDef(\advWave, {
					|buf, gate=1, freq=100, amp=1, pan=0, atk=0.01, dec=0.01, sus=1, rel=0.1, cur=4|
					var sig, env;
					env=EnvGen.ar(Env.adsr(atk,dec,sus,rel,amp,cur),gate,doneAction:2);
					sig={Osc.ar(buf, freq+SinOsc.ar(rrand(0.2,0.84), mul:2.5)+rrand(-0.3,0.3))}!8;
					sig=Splay.ar(sig,center:pan);
					sig=LPF.ar(sig, 5000);
					sig=LeakDC.ar(sig);
					Out.ar(~revBus, sig*env*1);
				}).add
			);

			2.wait.debug;
		});

	};
	~routine.play(quant: 4);
);

//////////////////////////////////////////////////////////////////////////////
// Pbind.
//////////////////////////////////////////////////////////////////////////////

(
p.stop;
TempoClock.tempo=100/60;
Pdefn(\oct, Prand([3,4,5],inf));
Pdefn(\deg, Prand([1,2,6,9],inf));
Pdefn(\amp, Pwhite(0.4,0.8,inf));
Pdefn(\atk, Pwhite(0.001, 0.05,inf));
Pdefn(\rel, Pwhite(0.01,2,inf));
Pdefn(\cur, 4);
Pdefn(\pan, Pwhite(-0.8,0.8,inf));
Pdefn(\dur,1/4);
p=Pbind(\instrument, \advWave,
	\buf, Prand(~w[0..9],inf),
	\octave, Pdefn(\oct),
	\scale, Scale.chromatic,
	\dur, Pdefn(\dur),
	\legato, 0.2,
	\degree, Pdefn(\deg),
	\amp, Pdefn(\amp),
	\pan, Pdefn(\pan),
	\atk, Pdefn (\atk),
	\rel, Pdefn(\rel),
	\cur, Pdefn(\cur)
).play(quant: 1);
);
)

//////////////////////////////////////////////////////////////////////////////
// Variations
//////////////////////////////////////////////////////////////////////////////

Pdefn(\pan, 0);
Pdefn(\pan, Pwhite(-0.4,0.4,inf));
Pdefn(\pan, Pwhite(-0.8,0.8,inf));
Pdefn(\pan, Pwhite(-1,1,inf));
Pdefn(\rel, Pwhite(0.01, 2,inf));
Pdefn(\rel, Pwhite(0.01, 8,inf));
Pdefn(\dur,1/4);
Pdefn(\dur, Prand([1/4,1/8,1/16],inf));

(
Pdefn(\deg, Pseq([\Emajor7_As].chordProg,inf));//Needs extension.
Pdefn(\amp, Pwhite(0.2,0.3,inf));
Pdefn(\atk, Prand([0.02, 0.05],inf));
)

(
Pdefn(\deg, Pseq([\Eminor7_As].chordProg,inf));//Needs extension.
Pdefn(\amp, Pwhite(0.2,0.3,inf));
Pdefn(\atk, Prand([0.02, 0.05],inf));
)

(
Pdefn(\deg, Prand([1,2,6,9]+2,inf));
Pdefn(\amp, Pwhite(0.4,0.8,inf));
Pdefn(\atk, Pwhite(0.001, 0.1,inf));
)

(
Pdefn(\deg, Prand([1,2,5,9]+2,inf));
Pdefn(\amp, Pwhite(0.4,0.8,inf));
Pdefn(\atk, Pwhite(0.001, 0.1,inf));
)

(
~routine.stop;
p.stop;
)
Author
418 PM
  • Platform:
  • Category: Synthesizer
  • Revision: 1.0
  • License: GNU General Public License family
  • Views: 133
  • Modified: 4 months ago
Chat about this patch on Discord!
Appreciate 2

Leave a Reply