http://varioussmallfires.blogspot.com/2011/07/fm-gong.html
SynthDef("fm-gong", { arg freq, dr = 1.0, amp = 1.0; var mod1sig, mod1f = freq * 1.16; var mod2sig, mod2f = freq * 3.14; var mod3sig, mod3f = freq * 1.005; var idx1a = 0.01 * mod1f; var idx1b = 0.30 * mod1f; var idx1scaler = idx1b - idx1a; var idx2a = 0.01 * mod2f; var idx2b = 0.38 * mod2f; var idx2scaler = idx2b - idx2a; var idx3a = 0.01 * mod3f; var idx3b = 0.50 * mod3f; var idx3scaler = idx3b - idx3a; var mod1env, mod2env, mod3env, ampenv; var carsig; mod1env = EnvGen.kr( Env(levels: [0,1,1,0], times: [0.75*dr, 0.24*dr, 0.01*dr]), doneAction: 2); mod2env = EnvGen.kr( Env(levels: [0,1,0], times: [0.02*dr, 0.98*dr]), doneAction: 2); mod3env = EnvGen.kr( Env(levels: [ 0, 0.3, 1, 0.5, 0], times: [0.15 * dr, 0.15 *dr, 0.45*dr, 0.25*dr]), doneAction: 2); // Exp curve... ampenv = EnvGen.kr( Env(levels: [ 0, 1, 0.001], times: [0.002, dr - 0.002], curve: \exp), doneAction: 2); mod1sig = SinOsc.ar(freq: mod1f); // envelope the signal, afterwards mod1sig = mod1sig * ((idx1a + idx1scaler) * mod1env); mod2sig = SinOsc.ar(freq: mod2f); // envelope the signal, afterwards mod2sig = mod2sig * ((idx2a + idx2scaler) * mod2env); mod3sig = SinOsc.ar(freq: mod3f); // envelope the signal, afterwards mod3sig = mod3sig * ((idx3a + idx3scaler) * mod3env); carsig = SinOsc.ar(freq + mod1sig + mod2sig + mod3sig); Out.ar(0, carsig * ampenv * amp); }).store
Possibly I can use 'mul' rather than envelope the modulator signals afterwards.