/*************************************************************************************/ /* Nate Gordon and Bill Reinsch, Assignment 3 / /*************************************************************************************/ /* Our patch is called "Chord Maker," which allows the user to construct chords. The GUI */ /* interface allows for the adjustment of the frequency and volume levels of four different */ /* sine/sawtooth waves (depending on the toggle). The latter three waves are a function */ /* of the relative frequency, in semitones, to the original root tone. The patch therefore */ /* allows for an experimental approach to chord construction. We also include a pan knob. */ /* The patch makes use of sine/sawtooth oscillators, frequency and amplitude modulation, */ /* various GUI operations, and the pan control. */ /********************************************************************************************/ { var w, a, b, c, d, da, e, f, g, h, ha, i, j, k, l, la, v, s, q, jim, tom, bill, elle, blue, green, lavender, claudia, heidi, mila, mila2, wave1, wave2, wave3, wave4, wave1a, wave2a, wave3a, wave4a, mix, panner, pannernumber; w = GUIWindow.new("Chord Maker", Rect.newBy( 128, 64, 664, 455 )); /* Wave#1 GUI Interface*/ /* GUI Interface provides for frequency adjustment, volume adjustment, and sine/saw wave toggle */ /* Includes descriptive string labels and numberical output of frequency and volume levels */ /* The first 8 lines of the interface code just draw and position the GUI boxes and sliders */ /* The "a.action = b.value..." just coordinates the user input/control with the GUI output */ a = NumericalView.new( w, Rect.newBy( 30, 68, 64, 20 ), "Frequency", 440, 60, 1000, 10, 'linear'); b = SliderView.new( w, Rect.newBy( 100, 68, 128, 20 ), "Frequency", 440, 60, 1000, 10, 'linear').knobColor_(rgb(24,34,205)); c = SliderView.new( w, Rect.newBy( 250, 68, 128, 20 ), "Volume", 1, 0, 1, 0.01, 'linear').knobColor_(rgb(237,24,30)); d = NumericalView.new( w, Rect.newBy( 400, 68, 64, 20 ), "Volume", 1, 0, 1, 0.01, 'linear'); da = SliderView.new( w, Rect.newBy( 500, 68, 128, 20 ), "Mix", 0.25, 0, 0.25, 0.001, 'linear').knobColor_(rgb(255,234,24)); StringView.new( w, Rect.newBy( 30, 36, 128, 20 ), "Frequency"); StringView.new( w, Rect.newBy( 303, 36, 128, 20 ), "Volume"); StringView.new( w, Rect.newBy( 500, 36, 128, 20 ), "Saw to Sine Mix"); a.action = { b.value = a.value }; b.action = { a.value = b.value }; c.action = { d.value = c.value }; d.action = { c.value = d.value }; /* Wave#2 GUI Interface*/ e = NumericalView.new( w, Rect.newBy( 30, 150, 64, 20 ), "Semitones", 0, 0, 24, 1, 'linear'); f = SliderView.new( w, Rect.newBy( 100, 150, 128, 20 ), "Harmony", 0, 0, 24, 1, 'linear').knobColor_(rgb(24,34,205)); g = SliderView.new( w, Rect.newBy( 250, 150, 128, 20 ), "Volume", 0, 0, 1, 0.01, 'linear').knobColor_(rgb(237,24,30)); h = NumericalView.new( w, Rect.newBy( 400, 150, 64, 20 ), "Volume", 0, 0, 1, 0.01, 'linear'); ha = SliderView.new( w, Rect.newBy( 500, 150, 128, 20 ), "Mix", 0.25, 0, 0.25, 0.001, 'linear').knobColor_(rgb(255,234,24)); StringView.new( w, Rect.newBy( 30, 118, 84, 20 ), "Semitones"); StringView.new( w, Rect.newBy( 130, 118, 128, 20 ), "Harmony"); StringView.new( w, Rect.newBy( 303, 118, 128, 20 ), "Volume"); StringView.new( w, Rect.newBy( 500, 118, 128, 20 ), "Saw to Sine Mix"); e.action = { f.value = e.value }; f.action = { e.value = f.value }; g.action = { h.value = g.value }; h.action = { g.value = h.value }; /* Wave#3 GUI Interface*/ i = NumericalView.new( w, Rect.newBy( 30, 314, 64, 20 ), "Semitones", 0, 0, 24, 1, 'linear'); j = SliderView.new( w, Rect.newBy( 100, 314, 128, 20 ), "Harmony", 0, 0, 24, 1, 'linear').knobColor_(rgb(24,34,205)); k = SliderView.new( w, Rect.newBy( 250, 314, 128, 20 ), "Volume", 0, 0, 1, 0.01, 'linear').knobColor_(rgb(237,24,30)); l = NumericalView.new( w, Rect.newBy( 400, 314, 64, 20 ), "Volume", 0, 0, 1, 0.01, 'linear'); la = SliderView.new( w, Rect.newBy( 500, 314, 128, 20 ), "Mix", 0.25, 0, 0.25, 0.001, 'linear').knobColor_(rgb(255,234,24)); StringView.new( w, Rect.newBy( 30, 200, 84, 20 ), "Semitones"); StringView.new( w, Rect.newBy( 130, 200, 128, 20 ), "Harmony"); StringView.new( w, Rect.newBy( 303, 200, 128, 20 ), "Volume"); StringView.new( w, Rect.newBy( 500, 200, 128, 20 ), "Saw to Sine Mix"); i.action = { j.value = i.value }; j.action = { i.value = j.value }; k.action = { l.value = k.value }; l.action = { k.value = l.value }; /* Wave#4 GUI Interface*/ elle = NumericalView.new( w, Rect.newBy( 30, 232, 64, 20 ), "Semitones", 0, 0, 24, 1, 'linear'); claudia = SliderView.new( w, Rect.newBy( 100, 232, 128, 20 ), "Harmony", 0, 0, 24, 1, 'linear').knobColor_(rgb(24,34,205)); heidi = SliderView.new( w, Rect.newBy( 250, 232, 128, 20 ), "Volume", 0, 0, 1, 0.01, 'linear').knobColor_(rgb(237,24,30)); mila = NumericalView.new( w, Rect.newBy( 400, 232, 64, 20 ), "Volume", 0, 0, 1, 0.01, 'linear'); mila2 = SliderView.new( w, Rect.newBy( 500, 232, 128, 20 ), "Mix", 0.25, 0, 0.25, 0.001, 'linear').knobColor_(rgb(255,234,24)); StringView.new( w, Rect.newBy( 30, 282, 84, 20 ), "Semitones"); StringView.new( w, Rect.newBy( 130, 282, 128, 20 ), "Harmony"); StringView.new( w, Rect.newBy( 303, 282, 128, 20 ), "Volume"); StringView.new( w, Rect.newBy( 500, 282, 128, 20 ), "Saw to Sine Mix"); elle.action = { claudia.value = elle.value }; claudia.action = { elle.value = claudia.value }; heidi.action = { mila.value = heidi.value }; mila.action = { heidi.value = mila.value }; /* Panner GUI Interface*/ panner = SliderView.new( w, Rect.newBy( 100, 400, 128, 20 ), "panner", 0, -1, 1, 0.01, 'linear').knobColor_(rgb(24,34,205)); pannernumber = NumericalView.new( w, Rect.newBy( 30, 400, 64, 20 ), "panner", 0, -1, 1, 0.01, 'linear'); StringView.new( w, Rect.newBy( 30, 370, 128, 20 ), "Panner"); panner.action = { pannernumber.value = panner.value }; pannernumber.action = { panner.value = pannernumber.value }; play({ /* Play Wave#1 -- Implements the sine and sawtooth waves */ /* Also allows for the user to change the wave frequencies/volume */ wave1 = SinOsc.ar( ControlIn.kr(a), 0, ControlIn.kr(d) * ControlIn.kr(da) ); wave1a = Saw.ar( ControlIn.kr(a), (ControlIn.kr(d) * 0.25) - (ControlIn.kr(d) * ControlIn.kr(da)) ); /* Play Wave#2 -- Plays sine/saw waves, but also accounts for relative frequency to wave #1 */ v = ControlIn.kr(e)/12; s = ControlIn.kr(a); q = s * (2**v); wave2 = SinOsc.ar( q, 0, ControlIn.kr(h) * ControlIn.kr(ha) ); wave2a = Saw.ar( q, (ControlIn.kr(h) * 0.25) - (ControlIn.kr(h) * ControlIn.kr(ha)) ); /* Play Wave#3* -- Plays sine/saw waves, but also accounts for relative frequency to wave#1 */ jim = ControlIn.kr(i)/12; tom = ControlIn.kr(a); bill = tom * (2**jim); wave3 = SinOsc.ar( bill, 0, ControlIn.kr(l) * ControlIn.kr(la) ); wave3a = Saw.ar( bill, (ControlIn.kr(l) * 0.25) - (ControlIn.kr(l) * ControlIn.kr(la)) ); /* Play Wave#4 -- Plays sine/saw waves, but also accounts for relative frequency to wave#1 */ blue = ControlIn.kr(elle)/12; green = ControlIn.kr(a); lavender = green * (2**blue); wave4 = SinOsc.ar( lavender, 0, ControlIn.kr(mila) *ControlIn.kr(mila2) ); wave4a = Saw.ar( lavender, (ControlIn.kr(mila) * 0.25) - (ControlIn.kr(mila) * ControlIn.kr(mila2)) ); mix = Mix.ar( [wave1, wave2, wave3, wave4, wave1a, wave2a, wave3a, wave4a]); /* Panner Implementation */ Pan2.ar( mix, ControlIn.kr(pannernumber)); }) ; w.close; }