// -Jeannie H. Lee // uses FM for creating randomly pitched piano and string-like sounds ( // GUI for Brasslike, Woodwindlike, and Percussionlike tones var w, piano1, piano2, strings1, strings2, strings3; var majorscale, ampMult, stringAmpMult; w = GUIWindow.new("FM synthesis", Rect.newBy( 148, 64, 205, 205 )) .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); // w.at(0), etc StringView.new( w, Rect.newBy( 8, 2, 175, 25 ), " FM piano & strings"); StringView.new( w, Rect.newBy( 18, 24, 105, 25 ), " melody noodler"); CheckBoxView.new( w, Rect.newBy( 25, 45,105, 25 ), "Piano1", 0, 0, 1, 0, 'linear') .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); CheckBoxView.new( w, Rect.newBy( 25, 65,105, 25 ), "Piano2", 0, 0, 1, 0, 'linear') .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); CheckBoxView.new( w, Rect.newBy( 25, 100,105, 25 ), "Strings1", 0, 0, 1, 0, 'linear') .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); CheckBoxView.new( w, Rect.newBy( 25, 125,105, 25 ), "Strings2", 0, 0, 1, 0, 'linear') .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); CheckBoxView.new( w, Rect.newBy( 25, 145,105, 25 ), "Strings3", 0, 0, 1, 0, 'linear') .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); // create scale multiplier to multiply fundamental (the tonic) // to any random note in diatonic scale majorscale = #[1, 1.12, 1.26, 1.334, 1.498, 1.5, 1.68, 1.89, 2]; // create amplitude multiplier to varying amplitude envelopes ampMult = #[0.15, 0.25, 0.5,0.5, 0.75]; stringAmpMult = #[0.15, 0.25, 0.4,0.5, 0.65]; piano1 = { arg checkbox; var changeParams; var scaleMult; var myAmpMult; var dur; changeParams = { scaleMult = majorscale.choose; dur = 0.45*#[0.125, 0.25, 0.375, 0.5, 0.75, 1.05, 1, 2].choose; myAmpMult = ampMult.choose; }; changeParams.value; // sets values for scale and amp multiplier and durations Spawn.ar({ arg spawn, i, synth; // carrier sin wav, cWav, with freq, cFreq var cWav, cFreq; // carrier amplitude envelope, cAmp var cAmp; // modulating mWav1, mWav2 with freq1 and freq2, and index 1 and 2 var mWav1, mWav2, fm1, fm2 , i1, i2; // mod wav 1 envelope and mod 2 wav envelope 2 amplitude var m1Amp, m2Amp; // change scale multiplier changeParams.value; cFreq = 200; fm1 = 200; fm2 = 800; i1 = 2.73; i2 = 0.68; spawn.nextTime = dur; // amplitude envelope for carrier sin osc wav cAmp = Env.new([0.25*myAmpMult,0.15*myAmpMult,0.075*myAmpMult,0.0375*myAmpMult,0.0175*myAmpMult,0],[0.05,0.05,0.15,0.25,0.75],'linear'); // amplitude envelope for modulating sin osc wav m1Amp = Env.new([1,0.6,0.3,0.15,0.07,0],[0.05,0.05,0.15,0.25,0.45],'linear'); m2Amp = Env.new([1,0.6,0.3,0.15,0.07,0],[0.05,0.05,0.15,0.25,0.45],'linear'); if (checkbox.value != 0.0 and: { 0.8.coin }, { // build fm patch mWav1 = SinOsc.ar(scaleMult*fm1, 0, i1*fm1); mWav2 = SinOsc.ar(scaleMult*fm2, 0, i2*fm2); cWav = SinOsc.ar(scaleMult*cFreq + mWav1 + mWav2, 0, EnvGen.ar(cAmp)); Pan2.ar(cWav, 1.0.rand2); }); }, 2); }; piano2 = { arg checkbox; var changeParams; var scaleMult, myAmpMult; var dur; changeParams = { scaleMult = majorscale.choose; myAmpMult = ampMult.choose; dur = #[ 0.1, 0.1, 0.2, 0.2, 0.2, 0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2, 0.6].choose; }; changeParams.value; Spawn.ar({ arg spawn, i, synth; // carrier sin wav, cWav, with freq, cFreq var cWav, cFreq; // carrier amplitude envelope, cAmp var cAmp; // modulating mWav1, mWav2 with freq1 and freq2, and index 1 and 2 var mWav1, mWav2, fm1, fm2 , i1, i2; // mod wav 1 envelope and mod 2 wav envelope 2 amplitude var m1Amp, m2Amp; // change scale multiplier changeParams.value; cFreq = 200; fm1 = 200; fm2 = 800; i1 = 2.73; i2 = 0.68; spawn.nextTime = dur; // amplitude envelope for carrier sin osc wav cAmp = Env.new([0.6*myAmpMult,0.4*myAmpMult,0.2*myAmpMult,0.05*myAmpMult,0.04*myAmpMult,0],[0.05,0.05,0.15,0.25,0.55],'linear'); // amplitude envelope for modulating sin osc wav m1Amp = Env.new([1,0.6,0.3,0.15,0.07,0],[0.05,0.05,0.15,0.25,0.45],'linear'); m2Amp = Env.new([1,0.6,0.3,0.15,0.07,0],[0.05,0.05,0.15,0.25,0.45],'linear'); if (checkbox.value != 0.0 and: { 0.8.coin }, { // build fm patch mWav1 = SinOsc.ar(scaleMult*fm1, 0, i1*fm1); mWav2 = SinOsc.ar(scaleMult*fm2, 0, i2*fm2); cWav = SinOsc.ar(scaleMult*cFreq + mWav1 + mWav2, 0, EnvGen.ar(cAmp)); Pan2.ar(cWav, 1.0.rand2); }); }, 2); }; strings1 = { arg checkbox; Spawn.ar({ arg spawn, i, synth; // carrier sin wav, cWav, with freq, cFreq var cWav, cFreq; // carrier amplitude envelope, cAmp var cAmp; // modulating wavs var mWav1, mWav2, mWav3; var fm1, fm2, fm3; var vibratoWav; var attackNoiseWav; var chiff; var scaleMult, dur, changeParams; // add envelope to each mod wav var f1Env; var myAmpMult; // modulating wav indices var i1, i2, i3; changeParams = { scaleMult = majorscale.choose; myAmpMult = stringAmpMult.choose; }; // change scale multiplier changeParams.value; cFreq = 200; fm1 = 200; fm2 =600; fm3 = 800; i1 = 1.415; i2 = 1.06; i3 = 0.088; // amplitude envelope for carrier sin osc wav cAmp = Env.new([0.1*myAmpMult,0.65*myAmpMult,0.45*myAmpMult,0.25*myAmpMult,0],[0.1,0.1,1.13,0.4],'linear'); // attack env chiff = Env.perc(0.0001, 0.2, 1, -4); vibratoWav = SinOsc.ar(5.5, 0, 0.021); attackNoiseWav = EnvGen.ar(chiff, BPF.ar( BrownNoise.ar(0.8), 2000, 0.02), 0, 1, 0, 1); f1Env =Env.new([0.1,1,0.75,0.65,0],[0.1,0.1,0.3,0.1],'linear'); if (checkbox.value != 0.0 and: { 0.8.coin }, { // build fm patch mWav1 = SinOsc.ar(scaleMult*fm1, 0, i1 * fm1); mWav2 = SinOsc.ar(scaleMult*fm2, 0, i2 * fm2); mWav3 = SinOsc.ar(scaleMult*fm3, 0, i3 * fm3); cWav = SinOsc.ar((vibratoWav+1)* (scaleMult*cFreq + mWav1 + mWav2+ mWav3), 0, 0.25); Pan2.ar(EnvGen.ar(cAmp, Mix.ar([ attackNoiseWav, cWav]),0, 1, 0,1), 1.0.rand2); }); }, 2, 1.1); }; strings2 = { arg checkbox; Spawn.ar({ arg spawn, i, synth; // carrier sin wav, cWav, with freq, cFreq var cWav, cFreq; // carrier amplitude envelope, cAmp var cAmp; // modulating wavs var mWav1, mWav2, mWav3; var fm1, fm2, fm3; var vibratoWav; var attackNoiseWav; var chiff; var scaleMult, dur, changeParams; // add envelope to each mod wav var f1Env; var myAmpMult; // modulating wav indices var i1, i2, i3; changeParams = { scaleMult = majorscale.choose; myAmpMult = stringAmpMult.choose; }; // change scale multiplier changeParams.value; cFreq = 200; fm1 = 200; fm2 =600; fm3 = 800; i1 = 1.415; i2 = 1.06; i3 = 0.088; // amplitude envelope for carrier sin osc wav cAmp = Env.new([0.1*myAmpMult,1*myAmpMult,0.75*myAmpMult,0.65*myAmpMult,0],[0.1,0.1,1.43,0.2],'linear'); // attack env chiff = Env.perc(0.0001, 0.2, 1, -4); vibratoWav = SinOsc.ar(5.5, 0, 0.02); attackNoiseWav = EnvGen.ar(chiff, BPF.ar( BrownNoise.ar(0.8), 2000, 0.02), 0, 1, 0, 1); f1Env =Env.new([0.1,1,0.75,0.65,0],[0.1,0.1,0.3,0.1],'linear'); if (checkbox.value != 0.0 and: { 0.8.coin }, { // build fm patch mWav1 = SinOsc.ar(scaleMult*fm1, 0, i1 * fm1); mWav2 = SinOsc.ar(scaleMult*fm2, 0, i2 * fm2); mWav3 = SinOsc.ar(scaleMult*fm3, 0, i3 * fm3); cWav = SinOsc.ar((vibratoWav+1)* (scaleMult*cFreq + mWav1 + mWav2+ mWav3), 0, 0.15); Pan2.ar(EnvGen.ar(cAmp, Mix.ar([ attackNoiseWav, cWav]),0, 1, 0,1), 1.0.rand2); }); }, 2, 1); }; strings3 = { arg checkbox; Spawn.ar({ arg spawn, i, synth; // carrier sin wav, cWav, with freq, cFreq var cWav, cFreq; // carrier amplitude envelope, cAmp var cAmp; // modulating wavs var mWav1, mWav2, mWav3; var fm1, fm2, fm3; var vibratoWav; var attackNoiseWav; var chiff; var scaleMult, dur, changeParams; // add envelope to each mod wav var f1Env; var myAmpMult; // modulating wav indices var i1, i2, i3; changeParams = { scaleMult = majorscale.choose; dur = 0.8 * #[0.125, 0.25, 0.375, 0.5, 0.75, 1.5, 1, 2].choose; myAmpMult = stringAmpMult.choose; }; // change scale multiplier changeParams.value; spawn.nextTime = dur; cFreq = 200; fm1 = 200; fm2 =600; fm3 = 800; i1 = 1.415; i2 = 1.06; i3 = 0.088; // amplitude envelope for carrier sin osc wav cAmp = Env.new([0.1*myAmpMult,1*myAmpMult,0.65*myAmpMult,0.45*myAmpMult,0],[0.1,0.1,1.75,0.2],'linear'); // attack env chiff = Env.perc(0.0001, 0.2, 1, -4); vibratoWav = SinOsc.ar(5.5, 0, 0.02); attackNoiseWav = EnvGen.ar(chiff, BPF.ar( BrownNoise.ar(0.8), 2000, 0.02), 0, 1, 0, 1); f1Env =Env.new([0.1,1,0.75,0.65,0],[0.1,0.1,0.3,0.1],'linear'); if (checkbox.value != 0.0 and: { 0.8.coin }, { // build fm patch mWav1 = SinOsc.ar(scaleMult*fm1, 0, i1 * fm1); mWav2 = SinOsc.ar(scaleMult*fm2, 0, i2 * fm2); mWav3 = SinOsc.ar(scaleMult*fm3, 0, i3 * fm3); cWav = SinOsc.ar((vibratoWav+1)* (scaleMult*cFreq + mWav1 + mWav2+ mWav3), 0, 0.15); Pan2.ar(EnvGen.ar(cAmp, Mix.ar([ attackNoiseWav, cWav]),0, 1, 0,1), 1.0.rand2); }); }, 2); }; // Play instruments Synth.play({ Mix.ar([ // piano and strings play! piano1.value(w.at(2)), piano2.value(w.at(3)), strings1.value(w.at(4)), strings2.value(w.at(5)), strings3.value(w.at(6)) ]); }); // close gui GUIWindow.closeAll; )