Last active
January 1, 2016 21:09
-
-
Save colinbdclark/8201964 to your computer and use it in GitHub Desktop.
Flocking version of the first example in the Mark Polishook's SuperCollider FM synthesis tutorial
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// Original SuperCollider code. | |
( | |
SynthDef("fm1", { | |
arg bus = 0, freq = 440, carPartial = 1, modPartial = 1, index = 3, mul = 0.05; | |
// index values usually are between 0 and 24 | |
// carPartial :: modPartial => car/mod ratio | |
var mod = SinOsc.ar( | |
freq * modPartial, | |
0, | |
freq * index * LFNoise1.kr(freq: 0.2, mul: 0.5, add: 0.5) | |
); | |
var car = SinOsc.ar( | |
freq * carPartial + mod, | |
0, | |
mul | |
); | |
Out.ar( | |
bus, | |
car | |
); | |
}).add; | |
) | |
Synth("fm1", [\bus, 0, \freq, 440, \carPartial, 1, \modPartial, 2.4]); | |
Synth("fm1", [\bus, 1, \freq, 442, \carPartial, 1, \modPartial, 2.401]); | |
*/ | |
// Flocking version. | |
// This version uses a single synth with different values for the left and right trees of unit generators. | |
// The SuperCollider version uses two different synths in order to ensure that each channel can be setup | |
// with different values without having to cut and paste. Infusion's IoC and options merging functionality | |
// enables this to be done without the overhead of an extra synth. | |
// | |
// You can see that there are a number of awkward points with the Flocking version: | |
// 1. the current inability to share unit generator references, requiring the frequency to be set | |
// in three separate places in the unit generator tree. | |
// 2. the inability to define flat "variable names," requiring the use of somewhat awkward EL paths | |
// (e.g. "mod.freq.mul" instead of "modPartial") and nested options structures when defining options | |
// overrides (e.g. { modUGenDef: { freq: { mul: 2.4 }}}). | |
// 3. the user needs to manually set flock.ugen.value to the correct rate; ideally there should be an | |
// "automatic" rate that enables the unit generator to set its rate based on the rates of its inputs. | |
// | |
// These issues will be addressed over time by: | |
// 1. enabling in-tree references to unit generators so that diamond-shaped graphs can be created | |
// and ugens can be shared throughout the tree | |
// 2. a user-defined "flat model" for synths, which enable users to map flat names to nested paths | |
// (e.g. inputs: { "modPartial": "mod.freq.mul", "freq": ["car.freq.value", "mod.freq.value", "mod.mul.value"] }) | |
// (this also solves #1, though in a less efficient way) | |
// 3. support for "auto" rate unit generators in the core | |
fluid.defaults("flock.fmSynth", { | |
gradeNames: ["flock.synth", "autoInit"], | |
components: { | |
left: { | |
type: "flock.fmSynth.ugens", | |
options: { | |
carUGenDef: { | |
freq: { | |
value: 440 | |
} | |
}, | |
modUGenDef: { | |
freq: { | |
value: 440, | |
mul: 2.4 | |
}, | |
mul: { | |
value: 440 | |
} | |
} | |
} | |
}, | |
right: { | |
type: "flock.fmSynth.ugens", | |
options: { | |
carUGenDef: { | |
freq: { | |
value: 442 | |
} | |
}, | |
modUGenDef: { | |
freq: { | |
value: 442, | |
mul: 2.401 | |
}, | |
mul: { | |
value: 442 | |
} | |
} | |
} | |
} | |
}, | |
synthDef: { | |
ugen: "flock.ugen.out", | |
sources: [ | |
"{left}.options.ugens", | |
"{right}.options.ugens" | |
] | |
} | |
}); | |
fluid.defaults("flock.fmSynth.ugens", { | |
gradeNames: ["fluid.littleComponent", "autoInit"], | |
carUGenDef: { | |
id: "car", | |
ugen: "flock.ugen.sin", | |
mul: 0.05, | |
phase: 0, | |
freq: { | |
ugen: "flock.ugen.value", | |
rate: "audio", | |
value: 440, // freq | |
mul: 1 // carPartial | |
add: "{that}.options.modUGenDef" | |
} | |
}, | |
modUGenDef: { | |
id: "mod", | |
ugen: "flock.ugen.sin", | |
freq: { | |
ugen: "flock.ugen.value", | |
value: 440 // freq | |
mul: 1 // modPartial | |
}, | |
phase: 0, | |
mul: { | |
ugen: "flock.ugen.value", | |
value: 440, // freq | |
mul: { | |
ugen: "flock.ugen.value", | |
value: 3 // index | |
mul: { | |
ugen: "flock.ugen.lfNoise", | |
rate: "control", | |
freq: 0.2, | |
options: { | |
interpolation: "linear" | |
}, | |
mul: 0.5, | |
add: 0.5 | |
} | |
} | |
} | |
}, | |
ugens: "{that}.options.carUGenDef" | |
}); | |
var synth = flock.fmSynth(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment