/* Electronic Band by Mehmet Iyigun and Heather McMillan This patch allows the user to mess around with a military band, changing the beat, the frequency and amplitude of drums, trumpets and the tune. It is fun to play with I will explain how each part works separately: the trumpet: the basic sound unit of the trumpet is the variable element. It is created using a Brown noise and an envelope. To create the melody of the trumpets, we seperate the melody into several parts. These parts are stored in the partX variables. To create the partX variables, we use the variables first and second, which are defined to be the element spawned for 1 or two beats. After that, we create our parts and the entire military variable by using the Cycle UGen. The military variable is then mixed into the other sounds using mix. the drum: the drum (which doesn't sound much like a drum) works almost exactly the same way the trumpet works. Instead of first, second, partX variables, the drum uses the dpartX variables. The sound unit for the drum is the delement variables which is created using an enveloped formant. the creation of the drum melody works just like the trumpet. We merge the parts into the drum variable using Cycle and then we mix it with the rest of the sounds the tune: since the tune has different frequencies, we could not use a unit sound variable. The tune is made up of 3 parts which are stored in variables tpartX. each of these parts are enveloped in tenv which is a linen envelope. After we create the tpartX variables using enveloped formants, we merge them into the tune variable using Cycle and then we mix it into the rest the cymbal: the cymbal works differently. Unlike the others which are made from parts, the cymbal is created all at once. We use the Klang Ugen with a decaying impulse as the initiator. Since the cymbol is created at the beginning and is not spawned again, we cannot change the parameters (amplitude, frequency, period) of the cymbal. We actually tried to create the cymbal using spawn, but then we got infinite spawning. After creation, the cymbal is mixed into the others. the global period variable governs the speed of the sounds exept the cymbal. since all the other sounds are spawned each time, we can change their properties. when the GUI elements are played with, we update the configurable variables (see below) and everything else (exept the cymbal) adapts to the new settings. */ ( // GUI VARIABLES var w, m_ampsv, d_ampsv, d_freqsv, t_ampsv, t_freqsv, beatsv; var m_ampnv, d_ampnv, d_freqnv, t_ampnv, t_freqnv, beatnv; // Other state variables var e, element,first, second, silence, part1, part2, part3, military1, military2; var part4, part5, part6, military; var dpart1, dpart2, denv, delement, drum; var cymbal; var tenv,tfirst, tsecond, tthird, tune; var output; var p; // number of partials per channel per 'cymbal'. // the CONFIGURABLE VARIABLES var period, drum_freq, tune_freq, military_amp, drum_amp, tune_amp, cymbal_amp; // INITIALIZE VARIABLES drum_freq = 200; tune_freq = 360; military_amp = 0.5; drum_amp = 0.8; cymbal_amp = 0.03; tune_amp = 0.5; p = 16; period = 0.8; tenv = Env.linen((8*period/14)/10, 8*(8*period/14)/10, (8*period/14)/10, 0.6); // CREATE GUI w = GUIWindow.new("Electronic Band", Rect.newBy( 142, 57, 631, 502 )); m_ampsv = SliderView.new( w, Rect.newBy( 230, 72, 306, 22 ), "SliderView", military_amp, 0, 1, 0, 'linear'); d_ampsv = SliderView.new( w, Rect.newBy( 230, 143, 306, 22 ), "SliderView", drum_amp, 0, 1, 0, 'linear'); d_freqsv = SliderView.new( w, Rect.newBy( 230, 180, 306, 22 ), "SliderView", drum_freq, 0, 2000, 0, 'linear'); t_ampsv = SliderView.new( w, Rect.newBy( 230, 316, 306, 22 ), "SliderView", tune_amp, 0, 1, 0, 'linear'); t_freqsv = SliderView.new( w, Rect.newBy( 230, 363, 306, 22 ), "SliderView", tune_freq, 0, 2000, 0, 'linear'); beatsv = SliderView.new( w, Rect.newBy( 230, 435, 305, 22 ), "SliderView", 1/period, 0.5, 2, 0, 'linear'); m_ampnv = NumericalView.new( w, Rect.newBy( 153, 73, 64, 20 ), "NumericalView", military_amp, 0, 1, 0, 'linear'); d_ampnv = NumericalView.new( w, Rect.newBy( 153, 143, 64, 20 ), "NumericalView", drum_amp, 0, 1, 0, 'linear'); d_freqnv = NumericalView.new( w, Rect.newBy( 153, 181, 64, 20 ), "NumericalView", drum_freq, 0, 2000, 0, 'linear'); t_ampnv = NumericalView.new( w, Rect.newBy( 153, 317, 64, 20 ), "NumericalView", tune_amp, 0, 1, 0, 'linear'); t_freqnv = NumericalView.new( w, Rect.newBy( 153, 363, 64, 20 ), "NumericalView", tune_freq, 0, 2000, 0, 'linear'); beatnv = NumericalView.new( w, Rect.newBy( 152, 435, 64, 20 ), "NumericalView", 1/period, 0.5, 2, 'linear'); StringView.new( w, Rect.newBy( 9, 73, 128, 20 ), "Trumpet Amplitude"); StringView.new( w, Rect.newBy( 9, 141, 128, 20 ), "Drum Amplitude"); StringView.new( w, Rect.newBy( 9, 178, 128, 20 ), "Drum Frequency"); StringView.new( w, Rect.newBy( 9, 316, 128, 20 ), "Tune Amplitude"); StringView.new( w, Rect.newBy( 9, 361, 128, 20 ), "Tune Frequency"); StringView.new( w, Rect.newBy( 9, 434, 128, 20 ), "Overall Beat"); // link the controls m_ampsv.action = {m_ampnv.value = m_ampsv.value; military_amp = m_ampnv.value;}; d_ampsv.action = {d_ampnv.value = d_ampsv.value; drum_amp = d_ampnv.value;}; d_freqsv.action = {d_freqnv.value = d_freqsv.value; drum_freq = d_freqnv.value;}; t_ampsv.action = {t_ampnv.value = t_ampsv.value; tune_amp = t_ampnv.value;}; t_freqsv.action = {t_freqnv.value = t_freqsv.value; tune_freq = t_freqnv.value;}; beatsv.action = {beatnv.value = beatsv.value; period = 1/beatnv.value;}; m_ampnv.action = {m_ampsv.value = m_ampnv.value}; d_ampnv.action = {d_ampsv.value = d_ampnv.value}; d_freqnv.action = {d_freqsv.value = d_freqnv.value}; t_ampnv.action = {t_ampsv.value = t_ampnv.value}; t_freqnv.action = {t_freqsv.value = t_freqnv.value}; beatnv.action = {beatsv.value = beatnv.value}; // envelope and element for trumpet e = Env.perc(2*period/50, 48*period/50, 1, -6); element = {EnvGen.ar(e, BrownNoise.ar(military_amp))}; // envelope and element for the drum denv = Env.perc(1*period/50, 49*period/50, 1, -3); delement = {EnvGen.ar(denv, Formant.ar(drum_freq, 400, 200, drum_amp) )}; // the cymbal cymbal = { var z, f1, f2; f1 = 1500; f2 = 4000; z = Array.fill(1, { `[ // sine oscil bank specification : y = Array.fill(p, { f1 + f2.rand} ), // frequencies nil, // amplitudes default to 1.0 Array.fill(p, { 1.0 + 4.0.rand }) // ring times ] }); Klank.ar(z, Decay.ar(Impulse.ar(7/(8*period)), 0.004, WhiteNoise.ar(cymbal_amp))); }; // melody for the military trumpet first = { Spawn.ar(element, 1,2*period/7, 1) }; second = { Spawn.ar(element, 1, period/7, 2) }; silence = {arg len; {Spawn.ar({EnvGen.ar(e, BrownNoise.ar(0.00000001))}, 1, len*period/7, 1)} }; part1 = {Cycle.ar([first, second, first, silence.value(2)], 1, nil, 2)}; part2 = {Cycle.ar([second, first], 1, nil, 3)}; part3 = {Cycle.ar([first, first, second, first, first, silence.value(4)], 1, nil, 1)}; military1 = { Cycle.ar([part1, first, part2, silence.value(2), part1, part3, silence.value(2)], 1, nil, 1) }; part4 = {Cycle.ar([first, second, first, first, first, first, second, first], 1, nil, 1)}; part5 = {Cycle.ar([first, second, second, second, first, first, first], 1, nil, 1)}; part6 = {Cycle.ar([second, first, second, first, first], 1, nil, 1)}; military2 = { Cycle.ar([part4, part5, silence.value(2), part4, part6, silence.value(6)], 1, nil, 1) }; military = {Cycle.ar([military1, military2], 1, nil, nil)}; // melody for the drum dpart1 = { Spawn.ar(delement, 1,8*period/7, 2) }; dpart2 = {Spawn.ar(delement, 1, 4*period/7, 3) }; drum = {Cycle.ar([dpart1, dpart2, silence.value(4)], 1, nil, nil)}; // melody for the tune tfirst = { Spawn.ar( {EnvGen.ar(tenv, Formant.ar(tune_freq, 2000, 800, tune_amp))}, 1, (8*period/14), 1) }; tsecond = { Spawn.ar( {EnvGen.ar(tenv,Formant.ar(1.5*tune_freq, 2000, 800, tune_amp))}, 1, (8*period/14), 1) }; tthird = { Spawn.ar( {EnvGen.ar(tenv,Formant.ar(0.8*tune_freq, 2000, 800, tune_amp))}, 1, (8*period/14), 1) }; tune = {Cycle.ar([tfirst, tsecond, tfirst,tthird], 1, nil, nil)}; output = {Mix.ar([military.value, drum.value, cymbal.value, tune.value])}; output.play; w.close; )