SuperCollider, コンピュータ

Bus and Group

If there are more than a couple of synths to form a stream of sound and they are connected by a bus, you have to take care of where each node should be. You may want to add some Groups to make it easier.
It may be possible to explain a bus as river; it conveys anything from higher to lower. If synth A is going to send data to synth B along a bus, synth A has to be at a higher point than synth B, which means synth A has to be ahead of synth B.
node's position
Below is an example of playing two streams of sound.
SynthDefs for triggers and sounds:

SynthDef(\conductor, {arg bpm=120, outBus=nil;
	var out;
	out = Impulse.kr(bpm/240);
	Out.kr(outBus, out);
}).send(s);
 
SynthDef(\trigger6, {arg inBus=nil, outBus=nil, bpm=120;
	var trig, env, out;
	trig = In.kr(inBus, 1);
	env = EnvGen.kr(
		Env.new([0, 1, 1, 0], [10e-10, 2-(2*(10e-10)), 10e-10]), 
		trig, 
		timeScale: 120/bpm
	);
	out = Impulse.kr(bpm*6/240)*env;
	Out.kr(outBus, out);
}).send(s);
 
SynthDef(\trigger8, {arg inBus=nil, outBus=nil, bpm=120;
	var trig, env, out;
	trig = In.kr(inBus, 1);
	env = EnvGen.kr(
		Env.new([0, 1, 1, 0], [10e-10, 2-(2*(10e-10)), 10e-10]), 
		trig, 
		timeScale: 120/bpm
	);
	out = Impulse.kr(bpm*8/240)*env;
	Out.kr(outBus, out);
}).send(s);
 
SynthDef(\aRhythmAndAccent, {arg outBus=nil, inBus=nil;
    var env, trig, seq, out;
    trig = In.kr(inBus, 1);
    seq = Drand([
		Dseq([1,2,1,2,1,0]),
		Dseq([1,0,1,2,1,0]),
		Dseq([1,2,1,2,1,2]),
		Dseq([1,0,1,2,1,2])
	], inf);
    out = Demand.kr(trig, 0, seq)*trig;
	Out.kr(outBus, out)
}).send(s);
 
SynthDef(\aPitch, {arg outBus=nil, inBus=nil;
    var trig, seq, out;
    trig = In.kr(inBus, 1);
    seq = Drand([
		Dseq([0,7,-2,0,0,5]+64),
		Dseq([-2,5,0,7,0,5]+64),
		Dseq([0,5,-2,0,-2,0]+64),
		Dseq([0,7,-2,0,-2,5]+64)
	], inf);
    out = Demand.kr(trig, 0, seq);
	Out.kr(outBus, out)
}).send(s);
 
SynthDef(\aSound , {
	arg inBus1 = nil, inBus2 = nil;
	var src, env, out, trig, freq;
	trig = In.kr(inBus1, 1);
	freq = In.kr(inBus2, 1);
	src = SinOsc.ar(freq.midicps);
	env = EnvGen.kr(Env.perc(0.001, 0.12), trig, trig*0.3);
	out = Pan2.ar(src*env, 0.3);
	Out.ar(0, out);
}).send(s);
 
SynthDef(\bRhythmAndAccent, {
	arg outBus=nil, inBus=nil;
	var trig, seq, out;
	trig = In.kr(inBus, 1);
	seq = Dseq([1,0,2,1,2,0,1,0], inf);
	out = Demand.kr(trig, 0, seq)*trig;
	Out.kr(outBus, out);
}).send(s);
 
SynthDef(\bPitch, {
	arg outBus=nil, inBus=nil;
	var trig, seq, out;
	trig = In.kr(inBus, 1);
	seq = Dseq([-2,0,5,7,0,7,-2,5]+40, inf);
	out = Demand.kr(trig, 0, seq);
	Out.kr(outBus, out);
}).send(s);
 
SynthDef(\bSound , {
	arg inBus1 = nil, inBus2 = nil;
	var src, env, out, trig, freq;
	trig = In.kr(inBus1, 1);
	freq = In.kr(inBus2, 1);
	src = Saw.ar(freq.midicps);
	env = EnvGen.kr(Env.perc(0.01, 0.1), trig, trig*0.3);
	out = Pan2.ar(src*env, -0.3);
	Out.ar(0, out);
}).send(s);

Here, an extra Group would be convenient; group 1 consists of a conductor node and beat trigger nodes, and group 2 is for demand ugen nodes and sounding nodes, which should be at the lower reach.
nodes, buses, groups

// add group 2 after group 1
s.sendMsg(\g_new, 2, 3, 1);
/*
control buses (index number and trigger signal flow)
the bus for general tempo --- index 0
the bus for 6-beat trigger --- index 1
the bus for 8-beat trigger --- index 2
the bus for rhythm and accent patterns a --- index 3
the bus for rhythm and accent patterns b --- index 4
the bus for pitch patterns a --- index 5
the bus for pitch patterns b --- index 6
group 1 --------------------------------> group 2
  conductor ---> beat triggers --->         demand ugens ---> sound generators
*/
 
// get ready for sounds
s.sendMsg(\s_new, \aSound, 3001, 1, 2, \inBus1, 3, \inBus2, 5);
s.sendMsg(\s_new, \bSound, 3002, 1, 2, \inBus1, 4, \inBus2, 6);
 
// get ready for patterns
s.sendMsg(\s_new, \aRhythmAndAccent, 2001, 0, 2, \inBus, 1, \outBus, 3);
s.sendMsg(\s_new, \aPitch, 2002, 0, 2, \inBus, 1, \outBus, 5);
 
s.sendMsg(\s_new, \bRhythmAndAccent, 2003, 0, 2, \inBus, 2, \outBus, 4);
s.sendMsg(\s_new, \bPitch, 2004, 0, 2, \inBus, 2, \outBus, 6);
 
// start conducting
s.sendMsg(\s_new, \conductor, 1001, 0, 1, \outBus, 0);
 
// sending 6-beat trigger to bus 1
s.sendMsg(\s_new, \trigger6, 1002, 1, 1, \inBus, 0, \outBus, 1);
// sending 8-beat trigger to bus 2
s.sendMsg(\s_new, \trigger8, 1003, 1, 1, \inBus, 0, \outBus, 2);
 
// tempo change
s.sendBundle(0.1, [\n_set, 1001, \bpm, 105], [\n_set, 1002, \bpm, 105], [\n_set, 1003, \bpm, 105]);
 
 
// free nodes
s.sendMsg(\n_free, 1001);
s.sendMsg(\n_free, 1002);
s.sendMsg(\n_free, 1003);
 
s.sendMsg(\n_free, 2001);
s.sendMsg(\n_free, 2002);
s.sendMsg(\n_free, 2003);
s.sendMsg(\n_free, 2004);
 
s.sendMsg(\n_free, 3001);
s.sendMsg(\n_free, 3002);

(Any correction would be greatly appreciated.)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です