/*************************************************************************************/ /* Eric Etu, Assignment 3 */ /*************************************************************************************/ /* I name my patch "6 Partials," which allows the user to play six sine waves simultaneously. By placing the sliders approximately in a vertical line, the user can create a set of 6 partials, anywhere along the long length of the equally-sized sliders. Also, since the sliders are to represent partials, each successive partial (if switched on with its selection box) gets progressively softer (emits at a lower amplitude) in order to suuport the concept of partials. */ /* Technical: Since I wished to focus on partials, the second partial need only allow the user to set the frequency as high as twice the maximum frequency of the max of the first partial. The third partial should go as high as 3 times that of the first, and so on. For the sake of round numbers and wanting to keep all frequencies below 20000 Hz, I used sliders whose maximums are at 3300, 6600, 9900, 13200, 16500, and 19800 Hz, respectively, even though the sliders are all of equal length. It follows then that the frequency sliders *should* be precisely lined up whenever we have hit upon a true set of partials. Although, since I did not set the minimums of my partials to zero (or even all to the same number), but the first one to 20, the second to 40, then 60, and so on, the allignment is a fraction off, but I chose to stick with this arrangement, as the endpoints (the min and max extremes) remain perfect sets of partials in this configuration. The interesting challenge to the user is to try to allign the 6 sliders in such a fashion that they do in fact create a set of partials--it's not difficult to hear when they're not alligned, as you'll soon see! I also set the amplitudes (of partials that are switched on) to get exponentially softer as we progress down the set. I chose to use a factor of 2. And now I invite you to experiment! */ /*************************************************************************************/ ( // DECLARE ALL VARIABLES. {var w, t, box1, slid1, num1, box2, slid2, num2, box3, slid3, num3, box4, slid4, num4, box5, slid5, num5, box6, slid6, num6; // DRAW THE GUI WINDOW. w = GUIWindow.new("panel", Rect.newBy(439, 126, 520, 230)); // DECLARE SLIDERS, THEIR NUMERICAL REPRESENTATIONS, AND THEIR LABELS. // EACH SET OF FOUR LINES REPRESENTS ONE HORIZONTAL LINE IN THE GUI, FROM LEFT TO RIGHT. box1 = CheckBoxView.new( w, Rect.newBy(5, 30, 15, 20), "", 0, 0, 1, 0, 'linear'); slid1 = SliderView.new( w, Rect.newBy(30, 30, 330, 20), "nil", 20, 20, 3300, 'exponential'); num1 = NumericalView.new( w, Rect.newBy( 370, 30, 50, 20 ), "nil", 20, 20, 3300, 'linear'); StringView.new( w, Rect.newBy(430, 30, 90, 20), "1st Partial"); box2 = CheckBoxView.new( w, Rect.newBy(5, 60, 15, 20), "", 0, 0, 1, 0, 'linear'); slid2 = SliderView.new( w, Rect.newBy(30, 60, 330, 20), "nil", 40, 40, 6600, 'exponential'); num2 = NumericalView.new( w, Rect.newBy( 370, 60, 50, 20 ), "nil", 40, 40, 6600, 'linear'); StringView.new( w, Rect.newBy(430, 60, 90, 20), "2nd Partial"); box3 = CheckBoxView.new( w, Rect.newBy(5, 90, 15, 20), "", 0, 0, 1, 0, 'linear'); slid3 = SliderView.new( w, Rect.newBy(30, 90, 330, 20), "nil", 60, 60, 9900, 'exponential'); num3 = NumericalView.new( w, Rect.newBy( 370, 90, 50, 20 ), "nil", 60, 60, 9900, 'linear'); StringView.new( w, Rect.newBy(430, 90, 90, 20), "3rd Partial"); box4 = CheckBoxView.new( w, Rect.newBy(5, 120, 15, 20), "", 0, 0, 1, 0, 'linear'); slid4 = SliderView.new( w, Rect.newBy(30, 120, 330, 20), "nil", 80, 80, 13200, 'exponential'); num4 = NumericalView.new( w, Rect.newBy( 370, 120, 50, 20 ), "nil", 80, 80, 13200, 'linear'); StringView.new( w, Rect.newBy(430, 120, 90, 20), "4th Partial"); box5 = CheckBoxView.new( w, Rect.newBy(5, 150, 15, 20), "", 0, 0, 1, 0, 'linear'); slid5 = SliderView.new( w, Rect.newBy(30, 150, 330, 20), "nil", 100, 100, 16500, 'exponential'); num5 = NumericalView.new( w, Rect.newBy( 370, 150, 50, 20 ), "nil", 100, 100, 16500, 'linear'); StringView.new( w, Rect.newBy(430, 150, 90, 20), "5th Partial"); box6 = CheckBoxView.new( w, Rect.newBy(5, 180, 15, 20), "", 0, 0, 1, 0, 'linear'); slid6 = SliderView.new( w, Rect.newBy(30, 180, 330, 20), "nil", 120, 120, 19800, 'exponential'); num6 = NumericalView.new( w, Rect.newBy( 370, 180, 50, 20 ), "nil", 120, 120, 19800, 'linear'); StringView.new( w, Rect.newBy(430, 180, 90, 20), "6th Partial"); // COORDINATE SLIDERS WITH NUMERICAL REPRESENTATION. // (WE NEEDED TO MAKE SURE THE NUMBER ACURATELY DESCRIBED THE POSITION OF THE SLIDER). num1.action = { slid1.value = num1.value }; slid1.action = { num1.value = slid1.value }; num2.action = { slid2.value = num2.value }; slid2.action = { num2.value = slid2.value }; num3.action = { slid3.value = num3.value }; slid3.action = { num3.value = slid3.value }; num4.action = { slid4.value = num4.value }; slid4.action = { num4.value = slid4.value }; num5.action = { slid5.value = num5.value }; slid5.action = { num5.value = slid5.value }; num6.action = { slid6.value = num6.value }; slid6.action = { num6.value = slid6.value }; // NOW, WE PLAY ALL 6 SLIDERS AT ONCE. IF ANY PARTIAL'S BOX IS UNCHECKED, IT'S // AMPLITUDE IS SET TO ZERO (NULL) AND THEREFORE WE DON'T HEAR IT. ALSO, AS // DESCRIBED ABOVE, EACH SLIDER GOING DOWN IS SET AT HALF THE VOLUME OF ITS // PREDECESOR, TO CREATE AN EXPONENTIAL ENVIRONMENT SO THAT THE HUMAN EAR CAN // MAKE OUT THE SIGNIFICANT CHANGES IN AMPLITUDE. Synth.play ({ SinOsc.ar(ControlIn.kr(slid1), 0, ControlIn.kr(box1) * 1) + SinOsc.ar(ControlIn.kr(slid2), 0, ControlIn.kr(box2) * 0.5) + SinOsc.ar(ControlIn.kr(slid3), 0, ControlIn.kr(box3) * 0.25) + SinOsc.ar(ControlIn.kr(slid4), 0, ControlIn.kr(box4) * 0.125) + SinOsc.ar(ControlIn.kr(slid5), 0, ControlIn.kr(box5) * 0.0625) + SinOsc.ar(ControlIn.kr(slid6), 0, ControlIn.kr(box6) * 0.03125); }); }.value )