Skip to content

SuperCollider quark for Waldorf Blofeld synth

Notifications You must be signed in to change notification settings

kasparsj/Blofeld

Folders and files

NameName
Last commit message
Last commit date

Latest commit

May 10, 2021
64f4990 · May 10, 2021
May 10, 2021
Aug 20, 2019
Aug 20, 2019
May 10, 2021
Apr 14, 2021

Repository files navigation

Blofeld quark

SuperCollider quark for working with Waldorf Blofeld

connect

// it's much better to use Blofeld's MIDIIn port for SuperColler's MIDIOut, instead of USB
// also connect the USB cable to receive sysex messages coming from Blofeld
~blofeld = Blofeld.new.connect("Blofeld", ""); // deviceName, portName

select a random sound

var bank = rrand(0, 7);
var program = rrand(0, 127);
~blofeld.selectSound(bank, program);

request sound

// requires connected USB or MIDIOut from Blofeld
~blofeld.editBuffer.download({|sound|
	sound.printInfo;
	//sound.printInfo(true); // print full info
	sound[\filter1Type].postln;
});
// print implemented param names
BlofeldSound.byName.keys.postln;

init sound

~blofeld.editBuffer.init();

randomize sound

~blofeld.editBuffer.randomize(); // randomize everything
~blofeld.editBuffer.randomize(\filter1); // randomize filter1 only

change single param

~blofeld.editBuffer.set(\filter1Type, rrand(0, 10));
~blofeld.editBuffer.set(\filter1Cutoff, rrand(0, 127));

filter example

(
~blofeld = Blofeld.new.connect("Blofeld", "");
~blofeld.selectSound(1, 90); // select B091 (Clavinetro)
~blofeld.editBuffer.download({ // request selected sound parameter values
	~cutoff = ~blofeld.editBuffer.get(\filter1Cutoff);
	Pdef(\blofeldFilterExample, Ppar([
		Pspawn(Pbind(
			\method, \par,
			\pattern, Pfunc {
				// play random notes from Minor scale
				// change \filter1Resonance and ~cutoff target on every new note
				Pbind(
					\type, \blofeld,
					\midicmd, \noteOn,
					\scale, Scale.minor,
					\degree, Prand(Scale.minor.degrees, inf),
					\octave, Pwhite(2, 5, inf),
					\dur, 10,
					\filter1Resonance, Pwhite(0, 96, inf),
					\setCutoff, Pfunc {
						~cutoff = rrand(0, 127);
					},
				);
			},
			\delta, Pwhite(32, 128, inf)
		)),
		Pbind(
			\type, \blofeld,
			\dur, 0.25,
			\filter1Cutoff, Pfunc { |event|
				var speed = 1/3;
				var current = ~blofeld.editBuffer.get(\filter1Cutoff);
				current + ((~cutoff - current) * speed); // animate ~cutoff to target value
			},
		),
		Pbind(
			\type, \blofeld,
			\dur, 1,
			\effect2Mix, Pfunc {
				var value = ~blofeld.editBuffer.get(\effect2Mix) + 1;
				if (value > 127, { 0 }, { value }); // increase click-delay mix every second
			},
		),
	])).play;
});
)
Pdef(\blofeldFilterExample).stop;

wavetable example

(
// connect
~blofeld = Blofeld.new.connect("Blofeld", "");
)

(
// create 10 wavetables with increasing complexity in first 10 user slots
~createWavetable = { |i|
	// from: http://sccode.org/1-5bF#c876
	//random number of envelope segments
	var numSegs = i.linexp(0,9,4,40).round;
	// make every wave slightly different
	var wavetable = BlofeldWavetable.newFrom({
		//env always begins and ends with zero
		//inner points are random from -1.0 to 1.0
		[0]++({1.0.rand}.dup(numSegs-1) * [1,-1]).scramble++[0]
	}, {
		//greater segment duration variety in higher-index wavetables
		{exprand(1,i.linexp(0,9,1,50))}.dup(numSegs)
	}, {
		//low-index wavetables tend to be sinusoidal
		//high index wavetables tend to have sharp angles and corners
		{[\sine,0,exprand(1,20) * [1,-1].choose].wchoose([9-i,3,i].normalizeSum)}.dup(numSegs)
	});
	wavetable.slot_(80+i).displayName_("sine wt"+(i+1));
	~blofeld.upload(wavetable);
};
r = Routine({
	10.do { |i|
		("creating wt"+i).postln;
		~createWavetable.value(i);
		12.wait;
	}
});
r.play;
)

(
// multimode needs to be switched on manually
//~blofeld.multiMode(true); // <- will give you an error
// initialize first 10 channels
~blofeld.editBuffer.init({ "init sound finished".postln }, i, num: 10);
)

(
// patterns from: http://sccode.org/1-5bF#c876
t = TempoClock.new(90/60).permanent_(true);
~shapes = [Blofeld.shape[\sine]]++(Blofeld.shape[\user1]..Blofeld.shape[\user9]);
~blofeld.editBuffer.clear((0..9));
Pdef(\pad, Pbind(
	\type, \blofeld,
	\osc1Shape, Prand(~shapes[0..3], inf),
	\osc1FMSource, \noise,
	\osc1FM, Pwhite(4, 12),
	\osc2Shape, Prand(~shapes[0..3], inf),
	\osc2FMSource, \noise,
	\osc2FM, Pwhite(4, 12),
	\ampEnvAttack, Pexprand(36, 72),
	\ampEnvAttackLevel, 127,
	\ampEnvDecay, 127,
	\ampEnvSustain, 0,
	\ampEnvRelease, Pexprand(60, 120),
	\effect2Type, \reverb,
	\effect2Mix, 63,
	\lfo1Shape, \random,
	\lfo1Speed, Pwhite(1, 8),
	\lfo1StartPhase, rrand(0, 127),
	\lfo2Shape, \random,
	\lfo2Speed, Pwhite(1, 8),
	\lfo2StartPhase, rrand(0, 127),
	\lfo3Shape, \random,
	\lfo3Speed, 20,
	\lfo3StartPhase, rrand(0, 127),
	\modulation1Src, \lfo1,
	\modulation1Dst, \osc1Pitch,
	\modulation1Amount, Pwhite(55, 71), // -8..+8
	\modulation2Src, \lfo2,
	\modulation2Dst, \osc2Pitch,
	\modulation2Amount, Pwhite(55, 71),
	\modulation3Src, \lfo3,
	\modulation3Dst, \f1Pan,
	\modulation3Amount, 127,
	// midi
	\midicmd, \noteOn,
	\scale, Scale.minorPentatonic,
	\degree, Pfunc({
		(-12,-10..12).scramble[0..rrand(1,3)]
	}),
	\amp, Pexprand(0.05,0.07)*4,
	\dur, Pwrand([1,4,6,9,12],[0.35,0.25,0.2,0.15,0.05],inf),
	\chan, 0,
)).play;

Pdef(\pulse, Pbind(
	\type, \blofeld,
	\osc1Shape, Prand(~shapes[4..9], inf),
	\osc1FMSource, \noise,
	\osc1FM, 3,
	\ampEnvAttack, 1,
	\ampEnvDecay, 127,
	\ampEnvSustain, 0,
	\ampEnvRelease, Pexprand(12,36),
	\effect2Mix, 48,
	\lfo1Shape, \random,
	\lfo1Speed, Pwhite(1, 63),
	\lfo3Shape, \random,
	\lfo3Speed, 10,
	\lfo3StartPhase, rrand(0, 127),
	\modulation1Src, \lfo1,
	\modulation1Dst, \osc1Pitch,
	\modulation1Amount, Pwhite(50, 76), // -8..+8
	\modulation3Src, \lfo3,
	\modulation3Dst, \f1Pan,
	\modulation3Amount, 127,
	// midi
	\midicmd, \noteOn,
	\scale, Scale.minorPentatonic,
	\degree, Pseq([Prand([-15,-10,-5],24), Pseq([\],1)],inf) + Pstutter(25,Pwrand([0,2,-1],[0.78,0.1,0.12],inf)),
	\amp, Pseq([Pgeom(0.45,-1.dbamp,25)],inf)*2,
	\dur, Pseq([
		Pstutter(24,Pseq([1/4],1)),
		Prand([1,2,4,6,12],1)
	],inf),
	\chan, 1,
)).play(t, quant: 1);

Pdef(\melody, Pbind(
	\type, \blofeld,
	\osc1Shape, Pwrand([
		Pseq([~shapes[0]],4),
		Pseq([~shapes[1]],4),
		Pseq([~shapes[2]],4),
	],[9,3,1].normalizeSum,inf),
	\osc1FMSource, \noise,
	\osc1FM, 3,
	\ampEnvAttack, 0,
	\ampEnvSustain, 7,
	\ampEnvDecay, 127,
	\ampEnvRelease, 36,
	\effect2Mix, 63,
	\lfo1Shape, \random,
	\lfo1Speed, 10,
	\modulation1Src, \lfo1,
	\modulation1Dst, \osc1Pitch,
	\modulation1Amount, Pwhite(45, 81), // -8..+8
	// midi
	\midicmd, \noteOn,
	\midinote, Pxrand([
		Pseq([\,67,60,Prand([58,70,\])],1),
		Pseq([\,67,58,Prand([57,63,\])],1),
		Pseq([\,70,72,Prand([65,79,\])],1)
	],inf),
	\amp, Pseq([0,0.18,0.24,0.28],inf)*2,
	\dur, Prand([
		Pseq([Prand([12,16,20]),2,1.5,0.5],1),
		Pseq([Prand([12,16,20]),1.5,1,1.5],1),
	],inf),
	\chan, 2,
)).play(t, quant:1);

//infinite sequence of various finite rhythmic patterns
//all very short envelopes
Pdef(\rhythms,
	Pwrand([
		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(4, Prand(~shapes[5..9],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, 0,
			\ampEnvDecay, 127,
			\ampEnvRelease, Pstutter(2, Pexprand(0,1)),
			\effect2Mix, Pwhite(0, 32),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, 100,
			// midi
			\midicmd, \noteOn,
			\dur, Pseq([1/8],4),
			\freq, Pstutter(4, Prand([
				Pexprand(10000,20000,1),
				Pexprand(100,200,1),
				Pexprand(1,2,1)
			],inf)),
			\amp, Pgeom(0.9, -6.dbamp, 4) * Pstutter(4,Pexprand(0.3,1)),
			\chan, 3,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(2, Prand(~shapes[8..9],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, 0,
			\ampEnvDecay, 127,
			\ampEnvRelease, Pstutter(2, Pexprand(1,3)),
			\effect2Mix, Pwhite(0,32),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, Pstutter(2, Pexprand(10,200)),
			// midi
			\midicmd, \noteOn,
			\dur, Pseq([1/4],2),
			\freq, Pstutter(2, Pexprand(1,200)),
			\amp, Pgeom(0.4, -3.dbamp, 2)  * Pexprand(0.4,1),
			\chan, 4,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(6, Prand(~shapes[2..5],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, Pseq([4,0,0],1),
			\ampEnvDecay, 127,
			\ampEnvRelease, Pseq([0,Pexprand(1,7,48)],1),
			\effect2Mix, Pwhite(0,20),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, 100,
			// midi
			\midicmd, \noteOn,
			\dur, Pseq([1/2,1/4,1/4],1),
			\freq, Pstutter(6, Pexprand(1000,2000)),
			\amp, Pseq([0.1,0.5,0.3],1),
			\chan, 5,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(6, Prand(~shapes[2..5],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, Pseq([0,4,0],1),
			\ampEnvDecay, 127,
			\ampEnvRelease, Pseq([Pexprand(0,7,24),0,Pexprand(0,7,24)],1),
			\effect2Mix, Pwhite(0,20),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, 100,
			// midi
			\midicmd, \noteOn,
			\dur, Pseq([1/4,1/2,1/4],1),
			\freq, Pstutter(6, Pexprand(1000,2000)),
			\amp, Pseq([0.5,0.1,0.4],1),
			\chan, 6,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(6, Prand(~shapes[8..9],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, 0,
			\ampEnvDecay, 127,
			\ampEnvRelease, Pstutter(6, Pexprand(0,1)),
			\effect2Mix, Pwhite(0,20),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, Pstutter(6, Pexprand(10,100)),
			// midi
			\midicmd, \noteOn,
			\dur, Pseq([1/6],6),
			\freq, Pstutter(6, Pexprand(10,200)),
			\amp, Pgeom(0.7, -4.dbamp, 6)  * Pexprand(0.4,1),
			\chan, 7,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(2, Prand(~shapes[8..9],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, 0,
			\ampEnvDecay, 127,
			\ampEnvRelease, Pstutter(2, Pexprand(0,5)),
			\effect2Mix, Pwhite(7,63),
			\lfo1Shape, \random,
			\lfo1Speed, 1,
			\osc1FMSource, \lfo1,
			\osc1FM, Pstutter(2, Pexprand(10,100)),
			// midi
			\midicmd, \noteOn,
			\dur, Prand([
				Pseq([1/2],2),
				Pseq([1],2),
				Pseq([1,1/2,1/2],1),
				Pseq([2],1),
			],1),
			\freq, Pstutter(2, Pexprand(10,200)),
			\amp, 0.5,
			\chan, 8,
		),

		Pbind(
			\type, \blofeld,
			\osc1Shape, Pstutter(16, Prand(~shapes[0..9],inf)),
			\ampEnvAttack, 0,
			\ampEnvSustain, 0,
			\ampEnvDecay, 127,
			\ampEnvRelease, Pexprand(0,1),
			\effect2Mix, 0,
			// midi
			\midicmd, \noteOn,
			\dur, Prand([
				Pseq([1/16],16),
				Pseq([1/16],8)
			],1),
			\freq, Pstutter(16,Pexprand(1000,20000,inf)),
			\amp, 0.13,
			\chan, 9,
		),
	],
	[40,18,3,3,15,25,5].normalizeSum, inf)
).play(t,quant:1);
)

(
// stop everything
Pdef(\pad).stop;
Pdef(\pulse).stop;
Pdef(\melody).stop;
Pdef(\rhythms).stop;
)

About

SuperCollider quark for Waldorf Blofeld synth

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published