Hi guys,
I’ve a question related to timing, tempo clock and quantization.
In order to figure out the issue myself and to be better understand I’ve prepared a sort of an experiment in order to see if you can replicate such behaviour (at the end of the post you will find the complete code in order for an easier copy-paste).
Let’s start with the experiment!
Start the server
s.boot;
and also start the “metronome task”: an auto-sceduling task which will, at each new bar, print the current bar and beats number.
TempoClock.play({|beats, time, clock| ("bar: " ++(beats/4) ++ ", beats: " ++ beats).postln; 4}, quant:4);
});
You should see its output on the console every 4 secs (with 60 BPM and 4/4, the defaults).
Then evaluate these simple synth definitions:
(
SynthDef(\pulse, {
|freq=440, amp=1|
var env = EnvGen.ar(Env.perc(0.01, 0.5), doneAction:2);
var sig = LFPulse.ar(freq) * env * amp;
Out.ar(0, Pan2.ar(sig, 0.0));
};).add;
SynthDef(\saw, {
|freq=440, amp=1, gate=1|
var env = EnvGen.ar(Env.adsr(0.01, 0.01, 0.8, 1), gate, doneAction:2);
var sig = LPF.ar(LFSaw.ar(freq), 500) * env * amp;
Out.ar(0,Pan2.ar(sig, 0.0));
}).add;
)
Define some musical phrases to be used as a timing tests. These Pbinds represent these three bars:
As you can see, on bar A only the bass is playing with a quarter note on the first musical accent.
In bar B the pad enters with a C major chord while the bass plays a richer melody.
In bar C pad changes its chords creating a I-V-IV progression while the bass also adds some new elements.
(
~bass_barA = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([0],inf),
\amp, 0.5,
\dur, Pseq([4], inf),
);
~bass_barB = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([0,7,0,0],inf),
\amp, Pseq([0.5, 0.3, 0.5, 0.25], inf),
\dur, Pseq([0.5, 1, 0.5, 2], inf),
);
~bass_barC = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([7,7,7,0,0,4,7],inf),
\amp, Pseq([0.5, 0.33, 0.4, 0.25, 0.25], inf),
\dur, Pseq([0.25,0.25, 1, 0.5, 1, 0.5, 0.5], inf),
);
~pads_barB = Pbind(
\instrument, \saw,
\scale, Scale.major,
\root, 0, \octave, 4,
\degree, Pseq([[0, 2, 4]],inf),
\amp, 0.3,
\dur, Pseq([4], inf)
);
~pads_barC = Pbind(
\instrument, \saw,
\scale, Scale.major,
\root, 0, \octave, 4,
\degree, Pseq([[0,2,4], [1,4,6], [0,3,5]],inf),
\amp, 0.3,
\dur, Pseq([2, 1, 1], inf),
);
)
Now let’s start testing. Evaluate the following line:
Pdef(\bass, ~bass_barA).play(quant:4);
What do you obtain? Are you listening to a bass note every time the console prints a new bars/beat message?
I’m seeing exactly this: every time a new line appears on the console (which means we are just entered a brand new bar), the bass plays its quarter note on the first accent of the bar as stated in ~bass_barA musical phrase.
Now, lets move on the the other bars, evaluate bar B, listen carefully:
(
Pdef(\bass, ~bass_barB).play(quant:4);
Pdef(\pads, ~pads_barB).play(quant:4);
)
Are you listening to this?
move on, now evaluate bar C
(
Pdef(\bass, ~bass_barC).play(quant:4);
Pdef(\pads, ~pads_barC).play(quant:4);
)
Are you listening to this?
Back again to bar A
(
Pdef(\bass, ~bass_barA).play(quant:4);
Pdef(\pads).stop;
)
Did you hear any strange misalignment between the bass and the pads?
Any misalignment between the two instruments and (what I suppose is a precise clock) the “metronome task”?
Don’t stop the sound, continue playing. Try evaluating bar A, B, C again, in different order.
If I’m right, you will experience such misalignment.
Question is: why?
Maybe I haven’t correctly understood the use of the keyword “quant” but, using a value of 4 for it, shouldn’t it mean bass and pads musical phrases should start at the beginning of every new bar (which corresponds to the exact moment a new line is printed to the console by the “metronome task”)?
Is here something I’m missing?
I wish I was able to explain the issue.
Thank you so much for your help!
In case you are tired, stop the sound.
(
Pdef(\bass).stop;
Pdef(\pads).stop;
)
Here the complete code to make it easier to copy and paste:
// start the server
s.boot;
// and also start the "metronome task": an auto-sceduling task
// which will, at each new bar, print the current bar and beats number.
TempoClock.play({|beats, time, clock| ("bar: " ++(beats/4) ++ ", beats: " ++ beats).postln; 4}, quant:4);
});
// you should see its output on the console every 4 secs
// (using the default 60 BPM and 4/4)
// Then evaluate these simple synth definitions
(
SynthDef(\pulse, {
|freq=440, amp=1|
var env = EnvGen.ar(Env.perc(0.01, 0.5), doneAction:2);
var sig = LFPulse.ar(freq) * env * amp;
Out.ar(0, Pan2.ar(sig, 0.0));
};).add;
SynthDef(\saw, {
|freq=440, amp=1, gate=1|
var env = EnvGen.ar(Env.adsr(0.01, 0.01, 0.8, 1), gate, doneAction:2);
var sig = LPF.ar(LFSaw.ar(freq), 500) * env * amp;
Out.ar(0,Pan2.ar(sig, 0.0));
}).add;
)
// Define some musical phrases to be used as a timing tests.
// These Pbinds represent these three bars:
// As you see, on bar A only the bass is playing with a quater note on the
// first musical accent.
// In bar B the pad enters with a C major chord while the bass plays a
// richer melody.
// In bar C pad changes its chords creating a I-V-IV progression while
// the bass also adds some new element.
(
~bass_barA = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([0],inf),
\amp, 0.5,
\dur, Pseq([4], inf),
);
~bass_barB = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([0,7,0,0],inf),
\amp, Pseq([0.5, 0.3, 0.5, 0.25], inf),
\dur, Pseq([0.5, 1, 0.5, 2], inf),
);
~bass_barC = Pbind(
\instrument, \pulse,
\scale, Scale.major,
\root, 0, \octave, 3,
\degree, Pseq([7,7,7,0,0,4,7],inf),
\amp, Pseq([0.5, 0.33, 0.4, 0.25, 0.25], inf),
\dur, Pseq([0.25,0.25, 1, 0.5, 1, 0.5, 0.5], inf),
);
~pads_barB = Pbind(
\instrument, \saw,
\scale, Scale.major,
\root, 0, \octave, 4,
\degree, Pseq([[0, 2, 4]],inf),
\amp, 0.3,
\dur, Pseq([4], inf)
);
~pads_barC = Pbind(
\instrument, \saw,
\scale, Scale.major,
\root, 0, \octave, 4,
\degree, Pseq([[0,2,4], [1,4,6], [0,3,5]],inf),
\amp, 0.3,
\dur, Pseq([2, 1, 1], inf),
);
)
// Now lets start testing.
// Evaluate the following line:
Pdef(\bass, ~bass_barA).play(quant:4);
// What do you obtain? Are you listening to a bass note every time
// the console prints a new bars/beat message?
// I'm seeing exactly this: every new line is appearing in the console
// (which means we are just entered a brand new bar)
// the bass plays its quarter note on the first accent of the bar
// as stated in ~bass_barA musical phrase.
// Now, lets move on the the other bars
// evaluate bar B, listen carefully
(
Pdef(\bass, ~bass_barB).play(quant:4);
Pdef(\pads, ~pads_barB).play(quant:4);
)
// move on, now evaluate bar C
(
Pdef(\bass, ~bass_barC).play(quant:4);
Pdef(\pads, ~pads_barC).play(quant:4);
)
// back again to bar A
(
Pdef(\bass, ~bass_barA).play(quant:4);
Pdef(\pads).stop;
)
// Did you hear any strange misalignemet between the bass and the pads?
// Any misalignemet between the two instrument and (what I suppose is a precise clock)
// the "metronome task"?
// Don't stop the sound, continue playing. Try evaluating bar A, B, C again, in different order.
// If I'm right, you will experience such misalignement.
// Question is: why?
// Maybe I've not correctly undertood the use of the keyword "quant" but, using a value of 4 for it, shouldn't mean bass and pads musical phrases should start at the beginning of every new bar (which corresponds to the exact moment a new line is printed to the console by the "metronome task")?
// Is here something I'm missing?
// in case you are tired, stop the sound.
(
Pdef(\bass).stop;
Pdef(\pads).stop;
)