/*************************************************************************************/ /* Jeannie Lee and Brian Gray, Assignment 3 */ /*************************************************************************************/ // Last updated 12:20am 5-4-99 /* Our patch is called "Sylvester." It is the exact same toy that Sylvester the Cat uses to analyze and destroy that little yellow nightmare we all know to be Tweety. Help our big furry black friend annihilate his cutesy little opponent for all time. */ /* The gui consists of five tweeties. Each tweety is a bird instrument. Tweet1 is a sine oscillator with a triangle envelope. Tweet2 is the same with a percussive envelope. Tweet3 is a fast sine oscillator with a triangle envelope. Tweet4 takes freq values from an array (x4) and uses Dust to create density which is then decayed and passed through percussive envelope. Tweet5 works in the same way using a different array (x5) with higher frequencies. Each of the five instruments has five parameters: Beak Size, Mood Swing, Warbability, Spasmosis, and Near Death. Beak Size controls how large the synthetic bird's beak is, a representation of loudness. It works by adjusting the amplitude of the oscillating wave. Mood Swing determines how "high strung" the bird is. This is a function of frequency. Warbability determines how much the bird call fluctuates. It is equivalent to vibrato depth. Spasmosis determines the length of the fluctuation, and is equivalent to vibrato rate. (Both of the above parameters affect the oscillating wave, not the final output.) Near Death is a special function designed for this application. It begins with the synthesis of white noise, which is then enveloped under a sine wave. This compound wave is then multilpied by the bird sound as a whole. The audioperceptual effect is of wings rapidly flapping in panic. When Beak Size and Warbability are set to higher slider values, the Near Death function is more pronounced. Sly's Hunt is a special button which instantly eats (mutes) all the Tweeties. All variable declarations are accompanied by matching comments explaining their use. The general musical idea governing the patch is derived from our Sylvester vs. Tweety idea. Sylvester can agitate the Tweeties by raising their beak sizes and moods, then attack them using either the near death sliders or by hunting them (Sly's Hunt). When all the tweeties are active and warbling at a high rate, the mix's acoustic effect is quite astounding and unnerving because it does indeed sound like an entire flock of attacking Tweeties instead of just five. */ /*************************************************************************************/ ( var w; // for gui // oscillator for tweety 3 var osc; // envelopes, on-off button var e1,e2, e3, e4, e5, duckhunt; var e1b, e2b, e3b, e4b, e5b; // white noise generators mult to each tweety var white1, white2, white3, white4, white5; // vars for frequency modulating sin osc var s1; // array of frequencies for corresponding spawn event var x4, x5; // modulating sin oscs var vib1,vib2,vib3,vib4,vib5; // Checkbox vars for tweeters var tweet1, tweet2, tweet3, tweet4, tweet5; // Slider controls amps for individual tweeters var amp1, amp2, amp3, amp4, amp5; // silder for the frequency of the tweeters var freq1, freq2, freq3, freq4, freq5; // slider controls vibrato depth var vdepth1, vdepth2, vdepth3, vdepth4, vdepth5; // slider controls how fast the vibrato/warble rate is var vrate1, vrate2, vrate3, vrate4, vrate5; // silder general variable for the near death function var fatal1, fatal2, fatal3, fatal4, fatal5; //color vars var color1, color2, color3, color4, color5; color1 = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); color2 = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); color3 = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); color4 = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); color5 = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); //color= r g b w = GUIWindow.new("Sylvester vs. Tweety", Rect.newBy( 250, 350, 696, 225 )); w.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); duckhunt = ButtonView.new( w, Rect.newBy( 22, 168, 111, 40 ), "Sly's Hunt", 0, 0, 1, 0, 'linear'); tweet1 = CheckBoxView.new( w, Rect.newBy( 21, 36, 100, 15 ), "Tweetie Hana", 0, 0, 1, 0, 'linear'); tweet1.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); amp1 = SliderView.new( w, Rect.newBy( 148, 37, 100, 15 ), "amp1", 0, 0, 1, 0, 'linear'); amp1.backColor = color1; tweet2 = CheckBoxView.new( w, Rect.newBy( 21, 61, 100, 15 ), "Tweetie Dul", 0, 0, 1, 0, 'linear'); tweet2.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); amp2 = SliderView.new( w, Rect.newBy( 148, 62, 100, 15 ), "amp2", 0, 0, 1, 0, 'linear'); amp2.backColor = color1; tweet3 = CheckBoxView.new( w, Rect.newBy( 21, 86, 100, 15 ), "Tweetie Set", 0, 0, 1, 0, 'linear'); tweet3.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); amp3 = SliderView.new( w, Rect.newBy( 148, 87, 100, 15 ), "amp3", 0, 0, 1, 0, 'linear'); amp3.backColor = color1; tweet4 = CheckBoxView.new( w, Rect.newBy( 21, 111, 100, 15 ), "Tweetie Net", 0, 0, 1, 0, 'linear'); amp4 = SliderView.new( w, Rect.newBy( 148, 112, 100, 15 ), "amp4", 0, 0, 1, 0, 'linear'); tweet4.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); amp4.backColor = color1; tweet5 = CheckBoxView.new( w, Rect.newBy( 21, 136, 120, 15 ), "Tweetie Dahset", 0, 0, 1, 0, 'linear'); tweet5.backColor = Color.new(128 + 128.rand, 128 + 128.rand, 128 + 128.rand); amp5 = SliderView.new( w, Rect.newBy( 148, 137, 100, 15 ), "amp5", 0, 0, 1, 0, 'linear'); amp5.backColor = color1; StringView.new( w, Rect.newBy( 146, 13, 100, 18 ), "Beak Size (amp)"); freq1 = SliderView.new( w, Rect.newBy( 254, 37, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); freq1.backColor = color2; freq2 = SliderView.new( w, Rect.newBy( 254, 62, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); freq2.backColor = color2; freq3 = SliderView.new( w, Rect.newBy( 254, 87, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); freq3.backColor = color2; freq4 = SliderView.new( w, Rect.newBy( 254, 112, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); freq4.backColor = color2; freq5 = SliderView.new( w, Rect.newBy( 254, 137, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); freq5.backColor = color2; StringView.new( w, Rect.newBy( 252, 13, 100, 18 ), "Mood Swing(freqchnge)"); vdepth1 = SliderView.new( w, Rect.newBy( 360, 37, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vdepth1.backColor = color3; vdepth2 = SliderView.new( w, Rect.newBy( 360, 62, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vdepth2.backColor = color3; vdepth3 = SliderView.new( w, Rect.newBy( 360, 87, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vdepth3.backColor = color3; vdepth4 = SliderView.new( w, Rect.newBy( 360, 112, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vdepth4.backColor = color3; vdepth5 = SliderView.new( w, Rect.newBy( 360, 137, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vdepth5.backColor = color3; StringView.new( w, Rect.newBy( 358, 13, 100, 18 ), "Warblability"); vrate1 = SliderView.new( w, Rect.newBy( 466, 37, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vrate1.backColor = color4; vrate2 = SliderView.new( w, Rect.newBy( 466, 62, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vrate2.backColor = color4; vrate3 = SliderView.new( w, Rect.newBy( 466, 87, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vrate3.backColor = color4; vrate4 = SliderView.new( w, Rect.newBy( 466, 112, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vrate4.backColor = color4; vrate5 = SliderView.new( w, Rect.newBy( 466, 137, 100, 15 ), "SliderView", 0, 0, 1, 0, 'linear'); vrate5.backColor = color4; StringView.new( w, Rect.newBy( 464, 13, 100, 18 ), "Spasmosis"); fatal1 = CheckBoxView.new( w, Rect.newBy( 572, 37, 100, 15 ), "Die!", 0, 0, 1, 0, 'linear'); fatal1.backColor = color5; fatal2 = CheckBoxView.new( w, Rect.newBy( 572, 62, 100, 15 ), "Murder!", 0, 0, 1, 0, 'linear'); fatal2.backColor = color5; fatal3 = CheckBoxView.new( w, Rect.newBy( 572, 87, 100, 15 ), "McNuggets", 0, 0, 1, 0, 'linear'); fatal3.backColor = color5; fatal4 = CheckBoxView.new( w, Rect.newBy( 572, 112, 100, 15 ), "PoultryFest", 0, 0, 1, 0, 'linear'); fatal4.backColor = color5; fatal5 = CheckBoxView.new( w, Rect.newBy( 572, 137, 100, 15 ), "Tweeticide", 0, 0, 1, 0, 'linear'); fatal5.backColor = color5; StringView.new( w, Rect.newBy( 570, 13, 100, 18 ), "Near Death"); StringView.new( w, Rect.newBy( 150, 175, 500, 21 ), "I Tawt I Taw A Puddy Tat... I Deed, I Deed!"); //set the checkboxes to zero if sly's hunt is pressed duckhunt.action = { tweet1.value = 0; tweet2.value = 0; tweet3.value = 0; tweet4.value = 0; tweet5.value = 0; }; Synth.scope({ Spawn.ar({ if (tweet1.value > 0, { // if checkbox is checked, play TWEET1 e1 = Env.triangle(0.3,1); //triangle env for sinosc e1b = Env.sine(1,1); //envelop passed into env generator that's mult by white noise white1 = EnvGen.ar ( e1b, WhiteNoise.ar(0.15), 0, 1, 0, 3); s1 = SinOsc.ar(ControlIn.kr(freq1),0, 1); // modulating sin osc with slider control vib1 = SinOsc.ar(1 + (10 * ControlIn.kr(vrate1)), 0, 1 + (4 * ControlIn.kr(vdepth1))); //sin osc control vib //if whitenoise check box not checked play sinosc, else add white noise if(fatal1.value == 0, { EnvGen.ar(e1, vib1 * SinOsc.ar(XLine.kr(700,900.800.rand,2)*s1+XLine.kr(1500.1000.rand,800,1), 0, 0.5 * ControlIn.kr(amp1)), 0, 1, 0, 3); }, { white1*15*EnvGen.ar(e1, vib1 * SinOsc.ar(XLine.kr(700,900.800.rand,2)*s1+XLine.kr(1500.1000.rand,800,1), 0, 0.5 * ControlIn.kr(amp1)), 0, 1, 0, 3); }); })}, 1, 3) + // add spawns together //1000*ControlIn.kr(vdepth2) Spawn.ar({ if (tweet2.value > 0, { // if checkbox is checked, play TWEET2 e2b = Env.sine(1,1); // envelope for whitenoise white2 = EnvGen.ar ( e2b, WhiteNoise.ar(0.15), 0, 1, 0, 3); e2 = Env.perc(0.01, 1, 1, -4); //env for sinosc vib2 = SinOsc.ar(1 + (10 * ControlIn.kr(vrate2)), 0, 1 + (4 * ControlIn.kr(vdepth2))); // sin osc gives vib controls //if whitenoise check box not checked play sinosc, else add white noise if(fatal2.value == 0, { EnvGen.ar(e2, vib2 * SinOsc.ar(XLine.kr(2000*ControlIn.kr(freq2)+ 400.320.rand,2000*ControlIn.kr(freq2)+300,2) , 0,0.75 * ControlIn.kr(amp2)), 0, 1, 0, 3); }, { white2*15*EnvGen.ar(e2, vib2 * SinOsc.ar(XLine.kr(2000*ControlIn.kr(freq2)+ 400.320.rand,2000*ControlIn.kr(freq2)+300,2) , 0,0.75 * ControlIn.kr(amp2)), 0, 1, 0, 3); }); })}, 1, 6) + Spawn.ar({ if (tweet3.value > 0, { // if checkbox is checked, play TWEET3 e3b = Env.sine(1,1); // env for whitenoise white3 = EnvGen.ar ( e3b, WhiteNoise.ar(0.15), 0, 1, 0, 3); vib3 = SinOsc.ar(1 + (10 * ControlIn.kr(vrate3)), 0, 1 + (4 * ControlIn.kr(vdepth3))); // sinosc controls vib rate //osc is the fast sin which has fast sin in phase osc = vib3 * FSinOsc.ar(3800*ControlIn.kr(freq3)+XLine.kr(3870+3000.0.rand,3590,0.4), FSinOsc.kr(XLine.kr(20, 6, 1), 0.25 ,0.5)) * EnvGen.kr(Env.triangle(2.0.rand, 1.0.rand)); // control fast sin osc with random env triangle //if whitenoise check box not checked play sinosc, else add white noise if(fatal3.value == 0, { osc*ControlIn.kr(amp3)*0.5 //control amp of slider },{ white3*15* osc*ControlIn.kr(amp3)*0.5 //white noise multiplied in osc }); })}, 1, 3/5) + Spawn.ar({ if (tweet4.value > 0, { // if checkbox is checked, play TWEET4 e4b = Env.sine(1,1); // sin env for white noise white4 = EnvGen.ar ( e4b, WhiteNoise.ar(0.15), 0, 1, 0, 3); // array of frequencies x4 = #[3590, 3800, 3500, 2750, 2600]; // choose a different freq vib4 = SinOsc.ar(1 + (10 * ControlIn.kr(vrate4)), 0, 1 + (4 * ControlIn.kr(vdepth4))); //control sinosc with vibrate e4 = Env.adsr(0.02, 0.2, 0.00025, 1, 1, -4); // adsr env for sinosc //if whitenoise check box not checked play sinosc, else add white noise if(fatal4.value == 0, { Decay.ar(Dust.ar(12,2.5), 0.2, //exponential decay and density EnvGen.ar(e4, vib4*SinOsc.ar(1400*ControlIn.kr(freq4)+x4.choose, 0, 0.75*ControlIn.kr(amp4)), 0, 1, 0, 3)) }, { white4*15*Decay.ar(Dust.ar(12,2.5), 0.2, // mult with white noise EnvGen.ar(e4, vib4*SinOsc.ar(1400*ControlIn.kr(freq4)+x4.choose, 0, 0.75*ControlIn.kr(amp4)), 0, 1, 0, 3)) }); })}, 1, 3) + Spawn.ar({ if (tweet5.value > 0, { // if checkbox is checked, play TWEET5 x5 = #[4000, 4100, 4300, 4400]; //random freqs vib5 = SinOsc.ar(1 + (10 * ControlIn.kr(vrate5)), 0, 1 + (4 * ControlIn.kr(vdepth5))); //control sinosc with vibrate e5b = Env.sine(1,1); // sin env for white noise white5 = EnvGen.ar ( e5b, WhiteNoise.ar(0.15), 0, 1, 0, 3); e5 = Env.adsr(0.02, 0.2, 0.0025, 1, 1, -4); // env for sinosc //if whitenoise check box not checked play sinosc, else add white noise if(fatal5.value == 0, { EnvGen.ar(e5, vib5*SinOsc.ar(1800*ControlIn.kr(freq5)+x5.choose , 0, 0.6*ControlIn.kr(amp5)), 0, 1, 0, 3); }, { white5*15*EnvGen.ar(e5, vib5*SinOsc.ar(1800*ControlIn.kr(freq5)+x5.choose , 0, 0.6*ControlIn.kr(amp5)), 0, 1, 0, 3); }); })}, 1, 2) }); )