// Putting it into practice - basic FM

SynthDef("modulator",{ arg modfreq=10, index=1;
var sound;
sound = SinOsc.kr(modfreq, 0, index);
Out.kr(400, sound);
}).writeDefFile;

SynthDef("carrier",{ arg basefreq=330, vol=0.5;
var mod, sound;
mod = In.kr(400, 1);
sound = SinOsc.ar(basefreq+mod, 0, vol);
Out.ar(0, [sound, sound]);
}).writeDefFile;

s.sendSynthDef("modulator");
s.sendSynthDef("carrier");

x = Synth.head(s, "modulator");
y = Synth.tail(s, "carrier");

x.set("index", 40);
x.set("modfreq", 50);
x.set("modfreq", 100, "index", 80);

x.free;
y.free;

/*
Now let's say we want multiple copies of both synths running. Each pair will need an independent bus. One way to do this would be to create individual SynthDefs with hard coded bus inputs and outputs. A smarter way would be to use an argument instead!
*/

SynthDef("modulator",{ arg modfreq=10, index=1, outbus=400;
var sound;
sound = SinOsc.kr(modfreq, 0, index);
Out.kr(outbus, sound);
}).writeDefFile;

SynthDef("carrier",{ arg basefreq=330, vol=0.5, inbus=400;
var mod, sound;
mod = In.kr(inbus, 1);
sound = SinOsc.ar(basefreq+mod, 0, vol);
Out.ar(0, [sound, sound]);
}).writeDefFile;

s.sendSynthDef("modulator");
s.sendSynthDef("carrier");

a = Synth.head(s, "modulator");
b = Synth.after(a, "carrier");
c = Synth("modulator", ["outbus",401]);
d = Synth.after(c, "carrier", ["inbus",401]);
e = Synth("modulator", ["outbus",402]);
f = Synth.after(e, "carrier", ["inbus",402]);
g = Synth("modulator", ["outbus",403]);
h = Synth.after(g, "carrier", ["inbus",403]);
i = Synth("modulator", ["outbus",404]);
j = Synth.after(i, "carrier", ["inbus",404]);

Crucial.menu;

a.free;
b.free;
c.free;
d.free;
e.free;
f.free;
g.free;
h.free;
i.free;
j.free;