# Deterministic sync of oscillator phase

Hi. Newbie question: Is there a way to deterministically sync the phase and timing between oscillators?
If I run the code below, you can often but not always, hear a distortion, which I assume comes from the oscillators starting almost at the same time with aligned phases, leading to high peaks that get clipped. But it seems there is a delay in execution, causing the oscillator to by out of sync. Are my assumptions correct, and can I control it deterministically? What I want is for the sine waves to have the same phase and start at the same time.

Thanks,
HĂĄkan

``````(
{
{ [SinOsc.ar(110, 0, 0.6), SinOsc.ar(110, 0, 0.6)] }.play;
{ [SinOsc.ar(220, 0, 0.6), SinOsc.ar(220, 0, 0.6)] }.play;
{ [SinOsc.ar(440, 0, 0.5), SinOsc.ar(440, 0, 0.5)] }.play;
{ [SinOsc.ar(880, 0, 0.45), SinOsc.ar(880, 0, 0.45)] }.play;
}.play;
)
``````

Short answer, you can easily synchronize them, but the code you have doesnâ€™t.

The reason this is happening is your outer function is trying to send four other different functions to the server and youâ€™ll end up with an error. You can fix some syntax to get it to not throw an error, but the timing will be off since you have to make sure the UGen functions are synchronized with `s.bind`.

{}.play is a convenience method to build a temporary SynthDef with the UGen graph function and play it, so this is interpreted as â€śmake and play a SynthDef that makes and plays these four SynthDefs,â€ť which you canâ€™t do.

By default, the UGens in a function will be synchronized as long as they all play on the same function. So if you could evaluate what you have, the first {}.play would have two oscillators in sync, but they would not be in sync with the second {}.play oscillators because they wouldnâ€™t start at the same time. Observe:

``````{ [SinOsc.ar(110), SinOsc.ar(110)] }.plot;

{ [SinOsc.ar(400), SinOsc.ar(110)] }.plot;
``````

They all have an initial phase of 0. If you change the phase argument, theyâ€™ll be at that phase.

``````{ [SinOsc.ar(110, pi), SinOsc.ar(110)] }.plot;

{ [SinOsc.ar(400, pi), SinOsc.ar(110)] }.plot;
``````

A few other things about your code. If you want to just use a function to make sure this works, it looks like this, but as you had it before itâ€™s way too loud:

``````({
{ [SinOsc.ar(110, 0, 0.6), SinOsc.ar(110, 0, 0.6), SinOsc.ar(220, 0, 0.6), SinOsc.ar(220, 0, 0.6), SinOsc.ar(440, 0, 0.5), SinOsc.ar(440, 0, 0.5), SinOsc.ar(880, 0, 0.45), SinOsc.ar(880, 0, 0.45)].sum * 0.01
}.play)
``````

Several ways to improve this:

1. Make this a SynthDef and then play it. That way itâ€™s already been built on the server.
``````(
SynthDef(\mySynth, {
arg out = 0;
var sig = [
SinOsc.ar(110, 0, 0.6),
SinOsc.ar(110, 0, 0.6),
SinOsc.ar(220, 0, 0.6),
SinOsc.ar(220, 0, 0.6),
SinOsc.ar(440, 0, 0.5),
SinOsc.ar(440, 0, 0.5),
SinOsc.ar(880, 0, 0.45),
SinOsc.ar(880, 0, 0.45)].sum * 0.01;
Out.ar(out, sig);
)

Synth(\mySynth);
``````
1. You can (and itâ€™s far more idiomatic to) use iteration instead of typing out the same thing multiple times. You also donâ€™t need duplicates of the same UGen with the same arguments. I assume youâ€™re doing this to get stereo playback, but thereâ€™s a better way with `.collect`. See Eli Fieldsteelâ€™s tutorial on iteration for a more detailed explanation.
``````(
SynthDef(\mySynth, {
arg out = 0, freq = 110;
var sig = 4.collect{
arg i; //index value
var ratio = 2.pow(i);
SinOsc.ar(ratio * freq, 0);
};
sig = sig * [0.6, 0.6, 0.5, 0.45].normalizeSum; //so it's not so loud
sig = sig.sum.dup;
Out.ar(out, sig);
)

Synth(\mySynth);
``````
1. You could use `Pan2` instead of `.dup` or `!2` to control the panning.
``````(
SynthDef(\mySynth, {
arg out = 0, freq = 110, pan = 0; //add pan argument set to stereo center
var sig = 4.collect{
arg i; //index value
var ratio = 2.pow(i);
SinOsc.ar(ratio * freq, 0);
};
sig = sig * [0.6, 0.6, 0.5, 0.45].normalizeSum;
sig = Pan2.ar(sig, pan);
Out.ar(out, sig);