For instance, I know I can use randomness (eg Pwhite) and let sounds play while having ever changing random values, while I’m not sure how to achieve that outside of patterns. For example - if I’m not mistaken - using something like “rrand” when calling a synth without the use of a Pbind will give me one random value and stick with it, unless I manually change it.
Just some additional thoughts on this type of randomness. You can think of randomness in three different levels or degrees:
‘Once-and-for-all’. This is the type you have now. Random values are calculated once when you create the synthdef (this is the same for { }.play, which under the hood creates a synthdef for you). If you want new random values you need to recreate/reevaluate the synthdef.
‘Once-per-note (or node)’. New random values are created for each instance of the synth. This can be done server side using eg. the Rand ugen or language side and passed to the synth
‘Moving randomness’. This is best done on the server using ugens to move the panning around during the lifetime of the note.
(
// you need to create a synth input (arg) to be able to pass new values.
// Note that pan position is a value in the range -1, 1, where -1 is all the way left, 0 is center, and 1 is all the way right.
// Note also that I am using a shortcut for NamedControl for the array of pan values and that
// the array is filled with random values, like in the orignal code. The difference that now you can pass new values to the Synth.
// search the helpfiles for 'NamedControl' to learn more
SynthDef(\test, {
arg freq = 50, atk = 0.1, rel = 1,gate = 1, amp = 1, out = 0;
var harmonics = 12;
var env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction: 2);
var pan = \pan.kr({rrand(-1.0, 1.0)}!harmonics);
var sig = Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(freq * (count + 1),
mul: FSinOsc.kr(rrand(1/3, 1/6), mul: 0.5, add: 0.5 )),
pan[count], amp)
}
) / (2*harmonics);
Out.ar(out, sig * env)
}).add;
)
x = Synth(\test, [\pan, {rrand(-1.0, 1,0)}!12])
(
// everytime to you run this, you will get new random values for panning
x.set(\gate, 0);
x = Synth(\test, [\atk, 2, \rel, 2, \pan, {rrand(-1,0, 1.0)}!12])
)
x.set(\gate, 0)
(
// With a pattern. You get a new random note with new random pannning every 5 seconds
Pdef(\test,
Pbind(
\instrument, \test,
\freq, Prand([28, 30, 32, 33, 35].midicps, inf),
// the \freq value can also be expressed directly as a midinote number - for this to work,
// the synth input has to be named 'freq', so that is one of the reasons I changed it from 'fund' to 'freq'
// comment out the \freq and uncomment below
// \midinote, Prand([28, 30, 32, 33, 35], inf),
\legato, 1,
\atk, 2,
\rel, 2,
\pan, Ptuple({Pwhite(-1.0, 1.0)}!12, inf),
\dur, 5
)).play
)
Pdef(\test).stop
(
// using the Rand ugen to the same effect - each new instance of the synth generates new random values
SynthDef(\test, {
arg freq = 50, atk = 0.1, rel = 1,gate = 1, amp = 1, out = 0;
var harmonics = 12;
var env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction: 2);
var pan = \pan.kr({rrand(-1, 1)}!harmonics);
var sig = Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(freq * (count + 1),
mul: FSinOsc.kr(rrand(1/3, 1/6), mul: 0.5, add: 0.5 )),
Rand(-1, 1), amp)
}
) / (2*harmonics);
Out.ar(out, sig * env)
}).add;
)
x = Synth(\test)
(
// everytime to you run this, you will get new random values for panning
x.set(\gate, 0);
x = Synth(\test, [\atk, 2, \rel, 2])
)
x.set(\gate, 0);
(
// using ugens to move the panning, here LFNoise1 but there are many other ways to create 'dynamic randoness' on the server.
SynthDef(\test, {
arg freq = 50, atk = 0.1, rel = 1,gate = 1, amp = 1, out = 0;
var harmonics = 12;
var env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction: 2);
var sig = Mix.fill(harmonics,
{ arg count;
Pan2.ar(
FSinOsc.ar(freq * (count + 1),
mul: FSinOsc.kr(rrand(1/3, 1/6), mul: 0.5, add: 0.5 )),
LFNoise1.kr(1).range(-1, 1), amp)
}
) / (2*harmonics);
Out.ar(out, sig * env)
}).add;
)
x = Synth(\test, [\pan, {rrand(-1, 1)}!12]);
// you will hear panning changing over time.
x.set(\gate, 0);