«Livecode setup, with comments» by tedthetrumpet

on 08 Mar'17 10:08 in livecode algorave

My personal setup file for livecoding as at 8/03/2017, with some explanatory comments

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* my personal setup file for livecoding in sc, as at 8/03/2017, with some explanatory comments

The synths I use, in a separate file that gets loaded below: \slice \dice \warp \bf \bform \rh \rh2

Three effects are set up ready to go, reverb, comb delay and decimator. The two latter effects can be controlled with patterns:

Pbindef(\e, \type, \set) controls Synth \echo on ~ebus (args: \delay, \decay, \amp)
Pbindef(\m, \type, \set) controls Synth \mate on ~mbus (args: \rate, \bits, \amp)
Ndef(\r) reverb node, listening to ~rbus

Folders with drum(ish) hits, stereo or duplicated mono: "hitz01 soh hamburg iowaphil emf nl tw hitz02 hitz01a". hitz02 and hitz01a pre-ordered into simple 32 beat drum sequence.

Functions: ~changebufs, ~listbufs, ~listloops, ~rrest, ~rdur

Loops: a folder of roughly two-bar loops for slicing and/or granulating, mostly excerpts from old tv theme tunes. These get loaded twice, as stereo buffers and also as pairs of mono buffers. (Because that's the only way I could figure out how to granulate in stereo!?)

*/

(//setup
Pdef.all.clear; Pdefn.all.clear; Ndef.all.clear; // not sure if this actually works?
// quantize changes to even four beat bars
Pbindef.defaultQuant_(4); Pdefn.defaultQuant_(4);
s.waitForBoot{
	var path, files;
	f = #["lcode07synths.scd"]; // load synths and fx from separate file
	f.do {|x| x.loadRelative};
	s.sync;

	Buffer.freeAll;
	s.sync;

	// load loops
	path = "../sldiwaloops/".resolveRelative;
	files = (path ++ "*.aiff").pathMatch ++ (path ++ "*.aif").pathMatch;
	~l = files.collect({ |i|  Buffer.read(s, i)});
	~l2 = files.collect({ |i| 2.collect( {|c| Buffer.readChannel(s, i, channels: [c])}) });
	s.sync;

	// load samples

	~thebufs;
	~changebufs = {
		|x="hitz01a"|
		if ( "hitz01 soh hamburg iowaphil emf nl tw hitz02 hitz01a".find(x) != nil, // checking the subfolder is correct
			{	var path = "../bfsamples/".resolveRelative ++ x ++ "/";
				var files = (path ++ "*.aiff").pathMatch ++ (path ++ "*.aif").pathMatch;
				files = files.sort; // get them in order of name, not modified date!
				// first, free all the buffers
				~thebufs.do({|i| i.free});
				// now, read the new files in
				~thebufs = files.collect({ |i|  Buffer.read(s, i)});
				~bufs = ~thebufs.collect(_.bufnum);
				~listbufs.();
			},
			{"that's not a sample folder".error; nil});
	};
	~changebufs.(); // can use this to change buffers between songs/sets

	~listbufs = {
		([~bufs] ++[~thebufs.collect(_.path).collect(_.asPathName).collect(_.fileName)]).flop.do(_.postln);
		nil
	};

	~listloops = {
	([~l.collect(_.bufnum)]++[~l.collect(_.path).collect(_.asPathName).collect(_.fileName)]).flop.do(_.postln);
		nil
	};

	// mixer node for final reverb
	~rbus = Bus.audio(s, 2);
	Ndef(\r).put(0, { InFeedback.ar(~rbus, 2) }).fadeTime_(0.2).play;
	Ndef(\r).filter(1, { |x| JPverb.ar(x, t60:0.1, size:0.8)}).set(\wet1, 0.2);

	// fx setup
	~ebus = Bus.audio(s, 2);
	~e=Synth.tail(s, \echo, [in: ~ebus, delay:1/t.tempo/4, out: ~rbus]); // .tail? not sure why?
	Pbindef(\e,
		\type, \set,
		\id, ~e.nodeID,
		\args, #[\delay, \decay, \amp, \out],
		\out, ~rbus
	).play;

	~mbus = Bus.audio(s, 2);
	~m=Synth(\mate, [in: ~mbus, out: ~rbus]);
	Pbindef(\m,
		\type, \set,
		\id, ~m.nodeID,
		\args, #[\rate, \bits, \amp],
		\amp, 0.8,
		\out, ~rbus
	).play;

	s.sync;

};

// rhythm function for isRest, ~rrest.() defaults to 8, or use ~r.(16), ~r.(7) etc
// creates syncopated rhythms by concatenating two and three beat cells, always with a downbeat
~rrest = { |a=8|
	var rhythm;
	a=(a-1).mod(16);
	rhythm = if ( a>7,
		{({[[1,0,0], [1,0,1]].choose}!4 ++ [[1,0].dup.flatten]).scramble.flatten.collect(_.booleanValue.not) },
		{({[[1,0,0], [1,0,1]].choose}!2 ++ [[1,0]]).scramble.flatten.collect(_.booleanValue.not) }
	);
	rhythm=rhythm[0..a];
};

// rhythm function for dur, ~rdur.() defaults to 8, or use ~r.(16), ~r.(7) etc
// uses the same function as above to work with durations instead of isRest

~rdur = { |b=8|
	var x;
	x = ~rrest.(b).collect(_.not.asInteger);
	x = x.indicesOfEqual(1).replace(0, x.size).rotate(-1).differentiate;
};

t=TempoClock.default.tempo_(140/60);

// a collection of jazz chords in dorian mode, make some sort of sense if played in order
~jz=[
	[0,4,6,9],  [0,4,5,9],  [0,3,6,9],  [0,3,4,8],  [-1,3,4,8],  [-1,2,4,8],  [-1,2,5,8],  [-1,2,5,7],  [-1,2,4,7],  [-2,2,4,7],  [-2,1,4,7],  [-3,0,3,6],  [-3,1,2,6],  [-3,1,3,6],  [-3,2,3,6],  [-2,2,3,6],  [-1,2,3,7],  [0,2,4,8],  [0,3,5,8],  [2,4,6,8],  [3,4,6,9],  [3,5,7,10]
];

nil;
)

//////////// notes and examples /////////////////////////
// how to use the granulator, syntax for passing pairs of buffers (L&R) is a bit fiddly!
x=Synth(\warp, [\buf, [~l2[7]], \rate, -0.05, \amp, 0.4])
x.setn(\buf, ~l2[3])
Pbindef(\w, \type, \set, \id, x.nodeID, \args, #[\buf, \rate, \freq, \amp])
Pbindef(\w, \dur, 1/2, \note, Pbrown(0,12,1))
Pbindef(\w).quant_(0).play
Pbindef(\w, \buf, [~l2[2]])
Pbindef(\w, \amp,  0.4 * Pseries(25, -1, 26)/25) // fadeout, x still running
// useful bits
SynthDescLib.global.at(\mate)
Pbindef(\w).asCompileString.newTextWindow

// series of amplitude values for a basic snare pattern
2312.asBinaryDigits(16)/10
// a metronome
Pbindef(\tmetro, \dur, 1, \legato, 0.01, \note, Pseq([36,30,30,30], inf), \amp, 0.5).play(t, quant:4)
// very useful syntax, create a new random rhythm every four bars
Pbindef(\z, \buf, Pn(Plazy({Pseq({~bufs.choose}!16,4)})))
raw 5551 chars (focus & ctrl+a+c to copy)
reception
comments