CtkControl allocate and send values to a control bus

Part of the CompositionToolKit (Ctk) system. See Ctk help for more details

Class Methods

*new(numChans, initVal, starttime, bus, server) -

numChans- the number of channels to allocate. Defaults to 1.

initVal - the initial value to be placed on a bus. Defaults to 0.0.

starttime - if used in a CtkScore, specifies a time to write the initVal to the bus. Defaults to 0.0.

bus - the bus id to write values to. Defaults to nil, where an id will be allocated for you.

server - and instance of Server to write control values out to. Defaults to Server.default.

*play(numChans, initVal, starttime, bus, server) - create a new CtkControl and immediately make it

available for real time use.

*env(Env, starttime, addAction, target, bus, server)

*lfo(UGen, freq, low, high, phase, starttime, duration, addAction, target, bus, server)

play - enable an instance of CtkControl for real-time use

set(val, time) - set the value of CtkControl to val. If used in real-time, the time parameter schedules when the

change of value should occur. In NRT, schedules the change at time from the value of starttime (or

starttime + time)

bus - returns the id of the CtkControl bus.

free - returns the bus id to the allocation pool.

Examples:

s = Server.local.boot;

Server.default = s;

(

var pnotes, group, bus1, bus2, env, freq, control, task;

var cond;

cond = Condition.new;

Routine.run({

pnotes = CtkProtoNotes(

SynthDef(\test, {arg dur, freq, amp;

var env, envgen, src;

env = Control.names([\env]).kr(Env.newClear(8));

envgen = EnvGen.kr(env, timeScale: dur, doneAction: 2);

src = SinOsc.ar(freq, 0, amp * envgen);

Out.ar(0, Pan2.ar(src, Rand(-1.0, 1.0)));

}),

SynthDef(\control, {arg outbus, rate, low, hi;

Out.kr(outbus, LFNoise2.kr(rate).range(low, hi))

}),

SynthDef(\controlenv, {arg gate = 1, outbus;

var env;

env = Control.names([\env]).kr(Env.newClear(8));

Out.kr(outbus, EnvGen.kr(env, gate));

}).load(s)

);

s.sync(cond);

group = CtkGroup.play;

bus1 = CtkControl.play; // create a CtkControl for writing out to

bus2 = CtkControl.play; // create a CtkControl for writing out to

env = Env([0, 1, 0], [1, 4], [3, -4], 1);

// create a controlenv and a loop of CtkNotes to play inside the CtkGroup

freq = pnotes[\control].new(addAction: \head, target: group)

.outbus_(bus1) // need to use the .bus method on CtkControl to just pass in its bus id

.rate_(1)

.low_(100)

.hi_(1050)

.play;

control = pnotes[\controlenv].new(addAction: \head, target: group)

.outbus_(bus2) // need to use the .bus method on CtkControl to just pass in its bus id

.env_(env)

.play;

task = Task({

var reltime, dur;

reltime = env.releaseTime;

dur = 10;

// schedule the release of the global envelope

SystemClock.sched(dur - reltime, {

group.release;

});

// schedule the release of the Task

SystemClock.sched(dur, {

group.freeAll;

task.stop;

});

loop({

pnotes[\test].new(addAction: \tail, target: group)

.dur_(1)

.env_(Env([0, 1, 0], [0.5, 0.5], \sin))

.freq_(bus1) // if a CtkControl is passed in, the arg will be mapped to the

.amp_(bus2) // CtkControls bus

.play;

0.5.wait;

})

});

task.play;

})

)

Examples that set the value of the CtkControl in real-time, and take advantage of SynthDefs lag controls.

a = CtkNoteObject(

SynthDef(\test, {arg freq = 440, amp = 0;

Out.ar(0, Pan2.ar(SinOsc.ar(freq, 0, amp), LFNoise2.kr(0.3)))

}, [2, 1])

);

b = CtkControl.play(initVal: 440);

c = CtkControl.play(initVal: 0);

// create a new instance, and map the freq and amp parameters to the CtkControls

d = a.new.freq_(b).amp_(c).play;

c.set(0.4);

b.set(660);

// unmap the control

d.freq_(440);

// remap it

d.freq_(b);

// set the amp to 0.0

c.set(0.0);

// kill the node

d.free;

Examples that populate an instance of CtkScore. The CtkScore can then be rendered in NRT, played or saved as a file. See CtkScore for more examples.

(

var scpn, score, grainfun, gliss;

scpn = CtkProtoNotes(

SynthDef(\control, {arg outbus, rate, low, hi;

Out.kr(outbus, LFNoise2.kr(rate).range(low, hi))

}),

SynthDef(\test, {arg freq, amp, dur;

var env, envgen, src;

env = Env([0, 1, 0], [0.5, 0.5], \sin);

envgen = EnvGen.kr(env, timeScale: dur);

src = BPF.ar(WhiteNoise.ar(amp), freq, 0.01, amp * envgen);

Out.ar(0, Pan2.ar(src, Rand(-1.0, 1.0)));

})

);

score = CtkScore.new;

/*

creates a granular gesture of duration. Each grain is 0.1 seconds long, new grain every 0.02 seconds

*/

grainfun = {arg starttime, duration, ampenv, lowfreq, hifreq;

var now, note;

now = 0;

ampenv.times = ampenv.times.normalizeSum * duration; // scale the Env's time to the gestures

while({

// create a note... add it to the CtkScore

note = scpn[\test].new(starttime + now, 0.1)

.freq_(lowfreq.rrand(hifreq))

.amp_(ampenv[now])

.dur_(0.1);

score.add(note); // tell CtkScore to add the note

now = now + 0.02;

now < duration;

});

};

gliss = {arg starttime, duration, rate, lowfreq, hifreq;

var cbus, control, note, group;

cbus = CtkControl.new;

// run these processes within its own CtkGroup

group = CtkGroup.new(addAction: \head, target: 1).addTo(score);

control = scpn[\control].new(starttime, duration, \head, group)

.outbus_(cbus)

.rate_(rate)

.low_(lowfreq)

.hi_(hifreq)

.addTo(score); // tell CtkNote to add to a CtkScore

note = scpn[\test].new(starttime, duration, \tail, group)

.freq_(cbus)

.amp_(2)

.dur_(duration)

.addTo(score);

};

grainfun.value(1, 10, Env([0, 1, 0], [0.5, 0.5], [3, -5]), 440, 880);

grainfun.value(4, 4, Env([0, 1, 0], [0.5, 0.5], [3, -5]), 4400, 8800);

grainfun.value(6, 12, Env([0, 1, 0], [0.5, 0.5], [3, -5]), 300, 400);

grainfun.value(3, 10, Env([0, 1, 0], [0.5, 0.5], [3, -5]), 200, 200);

grainfun.value(1.5, 20, Env([0, 1, 0], [0.5, 0.5], [3, -5]), 7000, 7100);

5.do({arg i;

var j;

j = i + 1;

gliss.value(3 + (i + 4), 10.rrand(7), j.reciprocal, 440 * j, 880 * j);

});

// uncomment to play the CtkScore you have created

score.play(s);

// uncomment to write the score to a soundfile

//score.write("~/Desktop/test.aiff".standardizePath, 22,

// options: ServerOptions.new.numOutputBusChannels_(2));

// uncomment to save the CtkScore as a file

//score.saveToFile("~/Desktop/test.sc".standardizePath);

)

// basic lfo and env usage

s.boot;

a = CtkControl.lfo(LFSaw, 10, 1, 0, 0);

a.play;

c = CtkNoteObject(

SynthDef(\test, {arg freq, amp, pan;

Out.ar(0, SinOsc.ar(freq, 0, amp))

})

);

b = c.new().freq_(440).amp_(a).play

b.freq_(CtkControl.env(Env([440, 550], [5], \exp)));

b.amp_(0.1);

b.amp_(a);

b.freq_(z = CtkControl.lfo(LFNoise1, 1, 550, y = CtkControl.env(Env([550, 330], [10]))))

b.amp_(0.1);

b.amp_(CtkControl.lfo(LFNoise1, 1, 0.1, CtkControl.env(Env([0.1, 1.0], [2]))))

// wait at least 2 seconds

b.amp.high_(CtkControl.env(Env([1.0, 0.1], [10])))

b.amp.high_(1)

b.amp_(a);

// free the LFSaw

a.free

// free the synth

b.free;