<br />
Sawtooth Minimalism<br />
<br />
<br />
<br />
My colleague, <a href="https://www.jackiewalduck.org/">Jackie Walduck</a>, was showing students how to create phase music by putting loops out of synch in a DAW. Then I went home from teaching and created a PD patch to play low-pass filtered sawtooth waves, as an example for a different class.  I got curious how much easier it would be in SuperCollider and created a tiny program that did the same thing and set it going at the same time. Then I started it again. The phasing was fixed, but it called to mind the shifting relationships of earlier that day.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
This version is only SuperCollider, but it uses a non band limitted sawtooth to mimic phasor~ in PD.  This version is 7 minutes long, but the proper version should be about 3 hours.  I get lost in the phasing and feel relaxed.<br />
<br />
<br />
<br />
I&#8217;ve attached the code below. If you want to to last longer, look for the number 340 &#8211; that&#8217;s 5&#8217;40&#8221; in seconds. Make it as long as you&#8217;d like.<br />
<br />
<br />
<br />
s.waitForBoot({<br />
	var scale, dur, pb, steps=16, loops = 4, loop_calc, env_dur, db = -14, fade_in=40, decay = 20;<br />
<br />
	loop_calc = {|note_dur, section_dur|<br />
		var loop_dur, total_dur;<br />
<br />
		loop_dur = note_dur * steps * loops;<br />
		total_dur = loop_dur * (section_dur/loop_dur).ceil;<br />
	};<br />
<br />
	SynthDef(\saw, {|out=0, freq, amp, dur, pan|<br />
		var saw, env, lop, pan2;<br />
		saw = LFSaw.ar(freq);<br />
		lop = LPF.ar(saw, freq*4);<br />
		env = EnvGen.kr(Env.triangle(dur), doneAction:2);<br />
		pan2 = Pan2.ar(lop, pan, env);<br />
		Out.ar(out, pan2 * amp);<br />
	}).add;<br />
<br />
	//s.prepareForRecord("/home/celesteh/Documents/Pieces/SawtoothMinimalism/take-" ++ Date.getDate.rawSeconds ++".wav" , 2);<br />
<br />
	s.sync;<br />
<br />
	//s.record;<br />
<br />
	dur = 60 / 250; // 250 BPM<br />
<br />
	env_dur = loop_calc.(dur, 340) - (fade_in+ decay);<br />
	env_dur.postln;<br />
<br />
	scale = Scale.minorPentatonic(Tuning.choose(5));<br />
<br />
	pb = {|limit = 7|<br />
		Pbind(<br />
			\instrument, \saw,<br />
			\db, db,<br />
			\dur, dur,<br />
			\scale, scale,<br />
			\degree, Prout({<br />
				var loop;<br />
<br />
				inf.do({<br />
					loop = steps.collect({ /*scale.degrees&#91;5.rand]*/ limit.rand });<br />
					loop = loop.scramble;<br />
					loops.do({<br />
						loop.do({|step|<br />
							step.yield;<br />
						})<br />
					})<br />
				})<br />
			}),<br />
			//\midinote, Pkey(\add) + offset,<br />
			\out, 0<br />
		);<br />
	};<br />
<br />
	s.sync;<br />
<br />
	Pseq(&#91;<br />
		Pbindf(pb.value, \octave, 4, \pan, 0, \continue, Pn(1,loops*steps)),<br />
		Ptpar(&#91;<br />
			0, Pseq(&#91;<br />
				Pbindf(pb.value, \octave, 4, \pan, -75, \continue, Pn(1, loops*steps*4)),<br />
				Pbindf(pb.value(5), \octave, &#91;4, 5], \pan, -1, \db, Penv(&#91;db, db-2, db, db], &#91;fade_in,decay, env_dur])),<br />
				Pbindf(pb.value, \octave, 4, \pan, -0.88, \db, Pn(db+1, 1), \degree, &#91;0, 2], \dur, dur*8)<br />
			] ),<br />
			0.0008.rrand(dur/10), Pseq(&#91;<br />
				Pbindf(pb.value, \octave, 5, \pan, 75, \continue, Pn(1, loops*steps*4)),<br />
				Ptpar(&#91;<br />
					0, Pseq(&#91;Pbindf(pb.(5), \octave, &#91;4,5], \pan, 1, \db, Penv(&#91;db, db-2, db, db], &#91;fade_in,decay, env_dur])),<br />
						Pbindf(pb.value, \octave, 4, \pan, 0.88, \db, Pn(db+1, 1), \degree, &#91;1, 4], \dur, dur*8)]),<br />
					(dur * 0.3).rrand(dur*0.7), Pseq(&#91; Pbindf(pb.value,<br />
						\octave, 5,<br />
						\pan, Pwhite(-0.1, 0.1),<br />
						\dur, Pwhite((dur / -700), (dur/700)) + dur,<br />
						\db, Penv(&#91;-60, db+1, db, db], &#91;fade_in, decay, env_dur])),<br />
					Pbindf(pb.value, \octave, 5, \pan, 0, \db, Pn(db+1, 1), \degree, &#91;0, 3, 5], \dur, dur*8)<br />
					])<br />
				])<br />
			])<br />
<br />
		]),<br />
<br />

Music by Charles Céleste HUTCHINS

Music by Charles Céleste HUTCHINS

Sawtooth Minimalism

MAR 6, 20217 MIN
Music by Charles Céleste HUTCHINS

Sawtooth Minimalism

MAR 6, 20217 MIN

Description

Sawtooth Minimalism

My colleague, Jackie Walduck, was showing students how to create phase music by putting loops out of synch in a DAW. Then I went home from teaching and created a PD patch to play low-pass filtered sawtooth waves, as an example for a different class. I got curious how much easier it would be in SuperCollider and created a tiny program that did the same thing and set it going at the same time. Then I started it again. The phasing was fixed, but it called to mind the shifting relationships of earlier that day.





This version is only SuperCollider, but it uses a non band limitted sawtooth to mimic phasor~ in PD. This version is 7 minutes long, but the proper version should be about 3 hours. I get lost in the phasing and feel relaxed.

I’ve attached the code below. If you want to to last longer, look for the number 340 – that’s 5’40” in seconds. Make it as long as you’d like.

s.waitForBoot({
	var scale, dur, pb, steps=16, loops = 4, loop_calc, env_dur, db = -14, fade_in=40, decay = 20;

	loop_calc = {|note_dur, section_dur|
		var loop_dur, total_dur;

		loop_dur = note_dur * steps * loops;
		total_dur = loop_dur * (section_dur/loop_dur).ceil;
	};

	SynthDef(\saw, {|out=0, freq, amp, dur, pan|
		var saw, env, lop, pan2;
		saw = LFSaw.ar(freq);
		lop = LPF.ar(saw, freq*4);
		env = EnvGen.kr(Env.triangle(dur), doneAction:2);
		pan2 = Pan2.ar(lop, pan, env);
		Out.ar(out, pan2 * amp);
	}).add;

	//s.prepareForRecord("/home/celesteh/Documents/Pieces/SawtoothMinimalism/take-" ++ Date.getDate.rawSeconds ++".wav" , 2);

	s.sync;

	//s.record;

	dur = 60 / 250; // 250 BPM

	env_dur = loop_calc.(dur, 340) - (fade_in+ decay);
	env_dur.postln;

	scale = Scale.minorPentatonic(Tuning.choose(5));

	pb = {|limit = 7|
		Pbind(
			\instrument, \saw,
			\db, db,
			\dur, dur,
			\scale, scale,
			\degree, Prout({
				var loop;

				inf.do({
					loop = steps.collect({ /*scale.degrees[5.rand]*/ limit.rand });
					loop = loop.scramble;
					loops.do({
						loop.do({|step|
							step.yield;
						})
					})
				})
			}),
			//\midinote, Pkey(\add) + offset,
			\out, 0
		);
	};

	s.sync;

	Pseq([
		Pbindf(pb.value, \octave, 4, \pan, 0, \continue, Pn(1,loops*steps)),
		Ptpar([
			0, Pseq([
				Pbindf(pb.value, \octave, 4, \pan, -75, \continue, Pn(1, loops*steps*4)),
				Pbindf(pb.value(5), \octave, [4, 5], \pan, -1, \db, Penv([db, db-2, db, db], [fade_in,decay, env_dur])),
				Pbindf(pb.value, \octave, 4, \pan, -0.88, \db, Pn(db+1, 1), \degree, [0, 2], \dur, dur*8)
			] ),
			0.0008.rrand(dur/10), Pseq([
				Pbindf(pb.value, \octave, 5, \pan, 75, \continue, Pn(1, loops*steps*4)),
				Ptpar([
					0, Pseq([Pbindf(pb.(5), \octave, [4,5], \pan, 1, \db, Penv([db, db-2, db, db], [fade_in,decay, env_dur])),
						Pbindf(pb.value, \octave, 4, \pan, 0.88, \db, Pn(db+1, 1), \degree, [1, 4], \dur, dur*8)]),
					(dur * 0.3).rrand(dur*0.7), Pseq([ Pbindf(pb.value,
						\octave, 5,
						\pan, Pwhite(-0.1, 0.1),
						\dur, Pwhite((dur / -700), (dur/700)) + dur,
						\db, Penv([-60, db+1, db, db], [fade_in, decay, env_dur])),
					Pbindf(pb.value, \octave, 5, \pan, 0, \db, Pn(db+1, 1), \degree, [0, 3, 5], \dur, dur*8)
					])
				])
			])

		]),

		Pbind(
			\dur, dur,
			\freq, Prout({
				\rest.yield;
				//s.stopRecording;
			})
		)
	]).play;
});