//JEANNIE LEE\
 

// simple melody with ghost tones
// This is a test that plays three blind mice with ghost tones, or tones with missing
// fundamentals and just some upper harmonics.
(
// an orchestra and score player
e = Env.sine(1,1);

Synth.play({
 OrcScore.ar(
  // the orchestra
  [
   // Ghost Fund = 329.6 -- has 5th partial of 1648, 6th partial of 1977.6, 7th partial of 2307.2
   { arg spawn, i, synth, deltaTime, instrumentNum, amp = 0.2;
    EnvGen.ar(e, Mix.ar([ SinOsc.ar(1648, 0, amp), SinOsc.ar(1977.6, 0, amp), SinOsc.ar(2307.2, 0, amp)]));
   },

   // Ghost Fund = 293.7 -- has 5th partial of 1468.5, 6th partial of  1762.2, 7th partial of 2055.9
   { arg spawn, i, synth, deltaTime, instrumentNum, amp = 0.2;
    EnvGen.ar(e, Mix.ar([ SinOsc.ar(1468.5, 0, amp), SinOsc.ar(1762.2, 0, amp), SinOsc.ar(2055.9, 0, amp)]));
   },

   // Ghost Fund = 261.6 -- has 5th partial of 1308, 6th partial of 1569.6, 7th partial of 1831.2
   { arg spawn, i, synth, deltaTime, instrumentNum, amp = 0.2;
    EnvGen.ar(e, Mix.ar([ SinOsc.ar(1308, 0, amp), SinOsc.ar(1569.6, 0, amp), SinOsc.ar(1831.2, 0, amp)]));
   }
  ],
  // the score
  #[ // deltaTime, instrumentNum, ...
   [0.7, 0],
   [0.7, 1],
   [0.9, 2],
   [0.7, 0],
   [0.7, 1],
   [0.9, 2],
   [0.5, 2],
   [0.5, 2],
   [0.5, 2],
   [0.5, 2],
   [0.5, 1],
   [0.5, 1],
   [0.5, 1],
   [0.5, 1],
   [0.7, 0],
   [0.7, 1],
   [0.9, 2]
  ],
 1, nil, 1)
}))
 
 
 
 
 
 
 
 

// Waveshaping on FM piano and strings
// This patch uses waveshaping with Chebyshev polynomials
// on FM sounds of strings and piano- may crash computer

// -Jeannie H. Lee
// uses FM for creating randomly pitched piano and string like sounds
(

 // GUI for Brasslike, Woodwindlike, and Percussionlike tones
 var chebyTable, cAmpSlider, modIndexSlider, outputAmpSlider;
 var w, h, piano2, strings2 ;
 var majorscale, chebyButton, h2, h3, h4;
 var harm1,harm2;

   w = GUIWindow.new("chebystuff with Piano and Strings", Rect.newBy( 148, 64, 500, 275 ))
     .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand);
   // w.at(0), etc
 CheckBoxView.new( w, Rect.newBy( 25, 35,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, 75,105, 25 ), "Strings2", 0, 0, 1, 0, 'linear')
   .backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand);

 StringView.new( w, Rect.newBy(25, 115, 105, 25), "carrier Amp slider");
 cAmpSlider = SliderView.new( w, Rect.newBy(25, 145, 105, 25), "carrier amp slider", 0.5, 0, 12, 0.01, 'linear');
 StringView.new( w, Rect.newBy(25, 175, 105, 25), "output Amp slider");
  outputAmpSlider = SliderView.new( w, Rect.newBy(25, 205, 105, 25), "output Amp slider", 0.1, 0, 1.5, 0, 'linear');
 chebyButton = ButtonView.new( w, Rect.newBy( 25, 240, 105, 25 ), "New Cheby set", 0, 0, 1, 0, 'linear');

 chebyTable = Wavetable.chebyFill(512, [1]);
 WavetableView.new( w, Rect.newBy(178,  8, 280, 200), chebyTable, -1, 1).hElastic.vElastic;

 majorscale = #[1, 1.12, 1.26, 1.334, 1.498, 1.5, 1.68, 1.89, 2];

piano2 = { arg checkbox;

 var changeParams;
 var scaleMult;
 var dur;

 changeParams = {
  scaleMult = majorscale.choose;

 };
 changeParams.value;  // init scale multiplier
 
 

 Spawn.ar({ arg spawn, i, synth;

 // carrier sin wav, cWav, with freq, cFreq
 var cWav, cFreq, cWavOut;
 // 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;
 

  // amplitude envelope for carrier sin osc wav
  cAmp = Env.new([0.7,0.5,0.3,0.15,0.07,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, Plug.kr(cAmpSlider) );
   cWav = EnvGen.ar(cAmp, cWav, 0,1,0,1);
   cWavOut = Shaper.ar(chebyTable, cWav);

   Plug.kr( outputAmpSlider)*Pan2.ar(cWavOut, 1.0.rand2);
  });
 }, 2,1);
};
 

strings2 = { arg checkbox;

 Spawn.ar({ arg spawn, i, synth;

 // carrier sin wav, cWav, with freq, cFreq
 var cWav, cFreq, cWavOut;
 // 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 h1, h2, h3, h4, h5, h6,h7,h8,h9,h10,h11,h12,h13,h14, h15,h16,h17,h18;

 // modulating wav indices
 var i1, i2, i3;
 changeParams = {
  scaleMult = majorscale.choose;

 };
  // change scale multiplier
  changeParams.value;

 chebyButton.action =  {
  h1 = #[0,1].choose;
  h2 = #[0,1].choose;
  h3 = #[0,1].choose;
  h4 = #[0,1].choose;
  h5 = #[0,1].choose;
  h6 = #[0,1].choose;
  h7 = #[0,1].choose;
  h8 = #[0,1].choose;
  h9 = #[0,1].choose;
  h10 = #[0,1].choose;
  h11 = #[0,1].choose;
  h12 = #[0,1].choose;
  h13 = #[0,1].choose;
  h14 = #[0,1].choose;
  h15 = #[0,1].choose;
  h16 = #[0,1].choose;
  h17 = #[0,1].choose;
  h18 = #[0,1].choose;
 

  chebyTable = Wavetable.chebyFill(512, [h1,h2,h3, h4, h5, h6, h7,h8,h9,h10,h11,h12,h13, h14,h15,h16,h17,h18]);
  WavetableView.new( w, Rect.newBy(178,  8, 280, 200), chebyTable, -1, 1).hElastic.vElastic;
  h = HarmonicsDialog.new(chebyTable);
 };
 
 

  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,1,0.75,0.65,0],[0.1,0.1,2.3,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, Plug.kr(cAmpSlider));

   cWavOut = Shaper.ar(chebyTable, cWav);

   Plug.kr( outputAmpSlider)* Pan2.ar(EnvGen.ar(cAmp, Mix.ar([ attackNoiseWav, cWavOut]),0, 1, 0,1), 1.0.rand2);
  });
 }, 2, 2.5);
};

// Play instruments
Synth.scope({

  Mix.ar([
   // piano and strings play!
  piano2.value(w.at(0)),
  strings2.value(w.at(1))

 ]);

});
w.close;
 )
 
 
 
 
 
 
 
 
 

// -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;
 )