// title: Operator-synth_Isomorphic-version // author: Marty Carlton // description: // This is just a different keyboard layout for the code I found called "Operator". Thank you Alexander Lunt, wherever you might be! // I changed the weird/possibly wrong kind of keyboard layout first into something that resembled piano layout, then I changed it to an old favorite. // The Isomorphic layout can easily utilize the offset nature of the different rows of keys on a computer keyboard to play the same chord shapes for each chord type... as seen here: https://muted.io/isomorphic-keyboard/ // One other change I made, was to move some of the code nearer the beginning/top, because "select all" was stumbling on or missing that portion of code. // // Let me know if something doesn't work, or fix it yourself and repost! // code: //Code by Alexander Lunt // adjusted/changed by Marty Carlton ( ///////////////////////////////////////////////////////GUI Server.default.waitForBoot({ var fx; var fxSynth = { SynthDef.new(\masterFX, { arg input, pos = 0, delayTime = 0, decayTime = 0, level = 1; var in, snd, fb, delay, left, right, locIn; in = In.ar(input,1); locIn = LocalIn.ar(1, 0); snd = locIn + in; fb = DelayC.ar(snd*decayTime, 1, delayTime); LocalOut.ar( fb ); snd = Balance2.ar(snd, snd, pos, level); Out.ar(0, snd); }).add; fx = Synth.new(\masterFX, [\input, ~out]); }; var stringColor = Color.new255(250,250,210); var play = Button().states_([["play"]]).mouseOverAction_({helpView.string = "press the play button to play a note or press the keys on your board (q-i and y-, -> c-c', . and - are octave down and up)"}); var freqBox = NumberBox().value_(400).minWidth_(50).maxWidth_(80).clipLo_(0).mouseOverAction_({helpView.string = "basic frequency in Hz";}); var waveformMenu = Array.fill(4, {|i|PopUpMenu().items_(["SinOsc","LFTri","LFSaw","WhiteNoise"]).action_({modField.valueAction_(modField.value)}).mouseOverAction_({helpView.string = "current waveform for oscillator "++ b[i]})}); var harmBox = Array.fill(4, {|i| NumberBox().clipLo_(0.5).value_(1).mouseOverAction_({helpView.string = "Number box: frequency of oscillator "++ b[i] ++" = freq * harm + fine"})}); var fineBox = Array.fill(4, {|i| NumberBox().value_(0).mouseOverAction_({helpView.string = "Number box: frequency of oscillator "++ b[i] ++" = freq * harm + fine";})}); var phaseBox = Array.fill(4, {|i| NumberBox().clipLo_(-2pi).clipHi_(2pi).mouseOverAction_({helpView.string = "Number box: Phase offset or modulator of oscillator "++b[i]++" in radians"})}); var ampBox = Array.fill(4, {|i| NumberBox().clipLo_(0).value_(0.5).scroll_step_(0.1).mouseOverAction_({helpView.string = "Number box: Output of oscillator "++b[i]++" will be multiplied by this value"})}); var infoText = ["osc","wave","harm","fine","phase","amp","a","p","d","s","r","curve","freq:"]; var infoHelp = ["Four oscillators with names a, b, c and d", "waveform that shall be synthesized", "harmonics are the number of partial in relation to the basic frequency", "fine tuning in Hz", "Phase offset or modulator in radians", "Output will be multiplied by this value", "attack Time", "peak Level", "decay Time", "sustain Level", "release Time", "The shapes of connections between the nodes of the envelope view", "basic frequency in Hz"]; var info = Array.fill(infoText.size, {|i| StaticText().string_(infoText[i]).maxHeight_(10).stringColor_(stringColor).mouseOverAction_({helpView.string = infoHelp[i];})}); var w = Window("Operator", Rect(250, 445, 722, 220)); var modField = TextField().string_("a").mouseOverAction_({helpView.string = "modulation Field: type your formula which describes how the four oscillators shall be modulated and press enter. Possible are + and * operations (e.g. a*b+c*d or a*a*b+d)"}); var b = ["a","b","c","d"]; var buttonColor = [Color.red, Color.green, Color.blue, Color.yellow]; var oscText = Array.fill(4, {|i| Button().states_([[b[i], Color.black, buttonColor[i]]]).maxWidth_(17).maxHeight_(18).mouseOverAction_({helpView.string = "clicking on this button shows amplitude Envelope of oscillator " ++ b[i]})}); var oscShow1 = Array.fill(4, {|i| Button().states_([[nil, nil, buttonColor[i]]]).maxWidth_(10).maxHeight_(10).mouseOverAction_({helpView.string = "clicking on this button shows amplitude Envelope of oscillator " ++ b[i]})}); var oscShow2 = Array.fill(4, {|i| Button().states_([[nil, nil, buttonColor[i]]]).maxWidth_(17).maxHeight_(18).mouseOverAction_({helpView.string = "clicking on this button shows amplitude Envelope of oscillator " ++ b[i]})}); var envStretch = 0.2; var oct = 60; var attackBox = Array.fill(4, {|i| NumberBox() .maxWidth_(60) .clipLo_(0) .clipHi_(10) .scroll_step_(0.1) .value_(0.01) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({enV[i].value = [ [0, attackBox[i].value*envStretch, attackBox[i].value + decayBox[i].value*envStretch, attackBox[i].value + decayBox[i].value+ releaseBox[i].value*envStretch], [0, peakBox[i].value, sustainBox[i].value, 0]];}) .mouseOverAction_({helpView.string = "Number box: attack time of the amplitude envelope of oscillator "++b[i]++" in seconds"}) }); var peakBox = Array.fill(4, {|i| NumberBox() .maxWidth_(60) .clipLo_(0) .clipHi_(1) .scroll_step_(0.1) .value_(1) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({enV[i].value = [ [0, attackBox[i].value*envStretch, attackBox[i].value + decayBox[i].value*envStretch, attackBox[i].value + decayBox[i].value+ releaseBox[i].value*envStretch], [0, peakBox[i].value, sustainBox[i].value, 0]];}) .mouseOverAction_({helpView.string = "Number box: peak value of the amplitude envelope of oscillator "++b[i]++" between 0 and 1"}) }); var decayBox = Array.fill(4, { |i| NumberBox() .maxWidth_(60) .clipLo_(0) .clipHi_(10) .scroll_step_(0.1) .value_(0.3) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({enV[i].value = [ [0, attackBox[i].value*envStretch, attackBox[i].value + decayBox[i].value*envStretch, attackBox[i].value + decayBox[i].value+ releaseBox[i].value*envStretch], [0, peakBox[i].value, sustainBox[i].value, 0]];}) .mouseOverAction_({helpView.string = "Number box: decay time of the amplitude envelope of oscillator "++b[i]++" in seconds"}) }); var sustainBox = Array.fill(4, { |i| NumberBox() .maxWidth_(60) .clipLo_(0) .clipHi_(1) .scroll_step_(0.1) .value_(0.5) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({enV[i].value = [ [0, attackBox[i].value*envStretch, attackBox[i].value + decayBox[i].value*envStretch, attackBox[i].value + decayBox[i].value+ releaseBox[i].value*envStretch], [0, peakBox[i].value, sustainBox[i].value, 0]];}) .mouseOverAction_({helpView.string = "Number box: sustain value of the amplitude envelope of oscillator "++b[i]++" between 0 and 1"}) }); var releaseBox = Array.fill(4, {|i| NumberBox() .maxWidth_(60) .clipLo_(0) .clipHi_(20) .scroll_step_(0.1) .value_(1) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({enV[i].value = [ [0, attackBox[i].value*envStretch, attackBox[i].value + decayBox[i].value*envStretch, attackBox[i].value + decayBox[i].value+ releaseBox[i].value*envStretch], [0, peakBox[i].value, sustainBox[i].value, 0]];}) .mouseOverAction_({helpView.string = "Number box: release time of the amplitude envelope of oscillator "++b[i]++" in seconds"}) }); var curveBox = Array.fill(6, {|i| NumberBox() .maxWidth_(60) .clipLo_(-16) .clipHi_(16) .scroll_step_(1) .value_(-3) .mouseDownAction_({aEnv.layout.index_(i);}) .action_({|value| enV[i].curves = value.value }) .mouseOverAction_({helpView.string = "Number box: The shapes of connections between the nodes of the envelope view"}) }); //OscEnvs var envA = EnvelopeView() .value_([[0, attackBox[0].value*envStretch, attackBox[0].value + decayBox[0].value*envStretch, attackBox[0].value + decayBox[0].value+ releaseBox[0].value*envStretch], [0, peakBox[0].value, sustainBox[0].value, 0]]) .thumbSize_(7) .strokeColor_(Color.new(1,0,0)) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .minWidth_(170) .mouseOverAction_({helpView.string = "envelope view of oscillator a´s amplitude is a visualization of the values of the adsr number boxes (only editable through number boxes)"}); var envB = EnvelopeView() .value_([[0, attackBox[1].value*envStretch, attackBox[1].value + decayBox[1].value*envStretch, attackBox[1].value + decayBox[1].value+ releaseBox[1].value*envStretch], [0, peakBox[0].value, sustainBox[1].value, 0]]) .thumbSize_(7) .strokeColor_(Color.new(0,1,0)) .editable_(false) .alpha_(0.4 ).background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator b´s amplitude is a visualization of the values of the adsr number boxes (only editable through number boxes)"}); var envC = EnvelopeView() .value_([[0, attackBox[2].value*envStretch, attackBox[2].value + decayBox[2].value*envStretch, attackBox[2].value + decayBox[2].value+ releaseBox[2].value*envStretch], [0, peakBox[0].value, sustainBox[2].value, 0]]) .thumbSize_(7) .strokeColor_(Color.new(0,0,1)) .editable_(false).alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator c´s amplitude is a visualization of the values of the adsr number boxes (only editable through number boxes)"}); var envD = EnvelopeView() .value_([[0, attackBox[3].value*envStretch, attackBox[3].value + decayBox[3].value*envStretch, attackBox[3].value + decayBox[3].value+ releaseBox[3].value*envStretch], [0, peakBox[0].value, sustainBox[3].value, 0]]) .thumbSize_(7) .strokeColor_(Color.new(1,1,0)) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator d´s amplitude is a visualization of the values of the adsr number boxes (only editable through number boxes)"}); //pitchEnvs var pitchEnvA = EnvelopeView() .thumbSize_(7) .strokeColor_(Color.new(1,0,0)) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .minWidth_(170) .mouseOverAction_({helpView.string = "envelope view of oscillator a´s pitch. Visualization of the values of the number boxes. The first node represents the start point, the second the sustain point and the third the end point"}); var pitchEnvB = EnvelopeView() .value_() .thumbSize_(7) .strokeColor_(Color.new(0,1,0)) .editable_(false) .alpha_(0.4 ).background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator b´s pitch. Visualization of the values of the number boxes. The first node represents the start point, the second the sustain point and the third the end point"}); var pitchEnvC = EnvelopeView() .value_() .thumbSize_(7) .strokeColor_(Color.new(0,0,1)) .editable_(false).alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator c´s pitch. Visualization of the values of the number boxes. The first node represents the start point, the second the sustain point and the third the end point"}); var pitchEnvD = EnvelopeView() .value_() .thumbSize_(7) .strokeColor_(Color.new(1,1,0)) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of oscillator d´s pitch. Visualization of the values of the number boxes. The first node represents the start point, the second the sustain point and the third the end point"}); //FX var lfoStart = NumberBox().value_(1).clipLo_(0).action_({enV[4].value = [ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]}).mouseOverAction_({helpView.string = "Number box: start frequency of the lfo"}); var lfoSustain = NumberBox().value_(1).clipLo_(0).action_({enV[4].value = [ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]}).mouseOverAction_({helpView.string = "Number box: sustain frequency of the lfo"}); var lfoEnd = NumberBox().value_(1).clipLo_(0).action_({enV[4].value = [ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]}).mouseOverAction_({helpView.string = "Number box: end frequency of the lfo"}); var lfoAttack = NumberBox().value_(0.1).clipLo_(0).scroll_step_(0.1).action_({enV[4].value = [ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]}).mouseOverAction_({helpView.string = "Number box: attack time of the lfo in seconds"}); var lfoRelease = NumberBox().value_(1).clipLo_(0).scroll_step_(0.1).action_({enV[4].value = [ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]}).mouseOverAction_({helpView.string = "Number box: release time of the lfo in seconds"}); var lfoPhase = NumberBox().value_(0).clipLo_(-2pi).clipHi_(2pi).mouseOverAction_({helpView.string = "Number box: phase shift of the lfo in radians. Value is between -2pi and +2pi"}); var filterStart = NumberBox().value_(0).clipLo_(-100).action_({enV[5].value = [ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/2000+0.5, filterSustain.value/2000+0.5, filterEnd.value/2000+0.5] ]}).mouseOverAction_({helpView.string = "Number box: start point of the frequency filter in percentual relation to the basic frequency"}); var filterSustain = NumberBox().value_(0).clipLo_(-100).action_({enV[5].value = [ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/2000+0.5, filterSustain.value/2000+0.5, filterEnd.value/2000+0.5] ]}).mouseOverAction_({helpView.string = "Number box: sustain point of the frequency filter in percentual relation to the basic frequency"}); var filterEnd = NumberBox().value_(0).clipLo_(-100).action_({enV[5].value = [ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/2000+0.5, filterSustain.value/2000+0.5, filterEnd.value/2000+0.5] ]}).mouseOverAction_({helpView.string = "Number box: end point of the frequency filter in percentual relation to the basic frequency"}); var filterAttack = NumberBox().value_(0.1).clipLo_(0).scroll_step_(0.1).action_({enV[5].value = [ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/2000+0.5, filterSustain.value/2000+0.5, filterEnd.value/2000+0.5] ]}).mouseOverAction_({helpView.string = "Number box: attack time of the frequency filter in seconds"}); var filterRelease = NumberBox().value_(1).clipLo_(0).scroll_step_(0.1).action_({enV[5].value = [ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/2000+0.5, filterSustain.value/2000+0.5, filterEnd.value/2000+0.5] ]}).mouseOverAction_({helpView.string = "Number box: release time of the frequency filter in seconds"}); var rq = NumberBox().value_(1).clipLo_(0).clipHi_(1).scroll_step_(0.1).mouseOverAction_({helpView.string = "Number box: resonance of the frequency filter. 1 is the minimum and 0 the maximum"}); var lfoEnv = EnvelopeView() .value_([ [0, lfoAttack.value*envStretch, lfoAttack.value + lfoRelease.value * envStretch], [lfoStart.value/100, lfoSustain.value/100, lfoEnd.value/100] ]) .thumbSize_(7) .strokeColor_(Color.black) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of the low frequency oscillator (lfo)"}); var filterEnv = EnvelopeView() .value_([ [0, filterAttack.value*envStretch, filterAttack.value + filterRelease.value * envStretch], [filterStart.value/500+0.5, filterSustain.value/500+0.5, filterEnd.value/500+0.5] ]) .thumbSize_(7) .strokeColor_(Color.new(1,1,0)) .editable_(false) .alpha_(0.4) .background_(Color.new(1,1,1,0.1)) .curves_(-3) .mouseOverAction_({helpView.string = "envelope view of the frequency filter"}); var enV = [ envA, envB, envC, envD, lfoEnv, filterEnv, pitchEnvA, pitchEnvB, pitchEnvC, pitchEnvD]; var aEnv = View().layout_(StackLayout( enV[0], enV[1], enV[2], enV[3]; ).mode_(1)); var bEnv = View().layout_(StackLayout( enV[6], enV[7], enV[8], enV[9]; ).mode_(1)); //Keys var keyDict = (); //SAVE var saveModus = Button().states_([["SAVE"], ["SAVE", Color.black, Color.gray]]).action_({|value| stackLayout.index = 3; oscButton.value = 0; pitchButton.value = 0; fxButton.value = 0; value.value = 1;}).mouseOverAction_({helpView.string = "this button opens the save view. Different settings can be stored in a list within the operator"}).enabled_(false); //Views var helpButton = Button().states_([["help", Color.black],["help:", Color.black, Color.gray]]).action_({|value| if(value.value == 0, {w.acceptsMouseOver_(false); helpView.string="";}, { w.acceptsMouseOver_(true); helpView.string = "move your mouse over the number boxes and Views to see their description. Click on a number box and move the mouse up and down to change the values in it"; })}).mouseOverAction_({helpView.string = "move your mouse over the number boxes and Views. Click on a number box and move the mouse up and down to change the values in it";}); var helpView = StaticText().string_("").minWidth_(750).stringColor_(stringColor); // minWidth was 450 var oscButton = Button().states_([["OSC"], ["OSC", Color.black, Color.gray]]).action_({|v| stackLayout.index = 0; fxButton.value = 0; pitchButton.value = 0; saveModus.value = 0; v.value = 1}).mouseOverAction_({helpView.string = "this button opens the oscillator view. Here you can set values for four oscillators"}); var fxButton = Button().states_([["FX"], ["FX", Color.black, Color.gray]]).action_({|v| stackLayout.index = 1; oscButton.value = 0; pitchButton.value = 0; saveModus.value = 0; v.value = 1}).mouseOverAction_({helpView.string = "this button opens the fx view. Here you can set effect values for a low frequency oscillator (lfo) and a frequency filter"}); var pitchButton = Button().states_([["PITCH"], ["PITCH", Color.black, Color.gray]]).action_({|v| stackLayout.index = 2; oscButton.value = 0; fxButton.value = 0; saveModus.value = 0; v.value = 1}).mouseOverAction_({helpView.string = "this button opens the pitch view. Here you can set pitch envelopes for each oscillator"}); var modus = View().layout_(HLayout(oscButton, pitchButton, fxButton, saveModus, helpButton, helpView)).maxHeight_(50); var lfoMenu = PopUpMenu().items_(["off","sine", "tri", "saw"]).mouseOverAction_({helpView.string = "shows the current waveform of the lfo"}); var filterMenu = PopUpMenu().items_(["off","BPF", "LPF", "HPF"]).mouseOverAction_({helpView.string = "shows the current filter art. BPF->Band Pass Filter, LPF->Low Pass Filter, HPF->High Pass Filter"}); var oscView = View().background_(Color.gray(0.2,0.8)).layout_(GridLayout.rows( [info[0], info[1], info[2], info[3], info[4], info[5], nil,nil, info[6], info[7], info[8], info[9], info[10], info[11]], [oscText[0], waveformMenu[0], harmBox[0], fineBox[0], phaseBox[0], ampBox[0], [aEnv, rows:4], oscShow2[0],attackBox[0], peakBox[0], decayBox[0], sustainBox[0], releaseBox[0], curveBox[0]], [oscText[1], waveformMenu[1], harmBox[1], fineBox[1], phaseBox[1], ampBox[1],nil, oscShow2[1],attackBox[1], peakBox[1], decayBox[1], sustainBox[1], releaseBox[1],curveBox[1]], [oscText[2], waveformMenu[2], harmBox[2], fineBox[2], phaseBox[2], ampBox[2],nil,oscShow2[2], attackBox[2], peakBox[2], decayBox[2], sustainBox[2], releaseBox[2],curveBox[2]], [oscText[3], waveformMenu[3], harmBox[3], fineBox[3], phaseBox[3], ampBox[3],nil, oscShow2[3],attackBox[3], peakBox[3], decayBox[3], sustainBox[3], releaseBox[3],curveBox[3]], [[modField, columns: 14]] )); var pitchStart = Array.fill(4, {|i| NumberBox() .value_(0) .clipLo_(-100) .mouseOverAction_({helpView.string = "Number box: Start point of the pitch Envelope in percent and relation to the basic frequency"}) .action_({ bEnv.layout.index = i; enV[i+6].value = [[0, pitchAttack[i].value/5, pitchAttack[i].value+pitchRelease[i].value/5],[(pitchStart[i].value/200)+0.5, (pitchSustain[i].value/200)+0.5, (pitchEnd[i].value/200)+0.5]]}) });//percent of freq var pitchSustain = Array.fill(4, {|i| NumberBox() .value_(0) .clipLo_(-100) .mouseOverAction_({helpView.string = "Number box: Sustain point of the pitch Envelope in percent and relation to the basic frequency"}) .action_({ bEnv.layout.index = i; enV[i+6].value = [[0, pitchAttack[i].value/5, pitchAttack[i].value+pitchRelease[i].value/5],[pitchStart[i].value/200+0.5, pitchSustain[i].value/200+0.5, pitchEnd[i].value/200+0.5]]}) }); var pitchEnd = Array.fill(4, {|i| NumberBox() .value_(0) .clipLo_(-100) .mouseOverAction_({helpView.string = "Number box: End point of the pitch Envelope in percent and relation to the basic frequency"}) .action_({ bEnv.layout.index = i; enV[i+6].value = [[0, pitchAttack[i].value/5, pitchAttack[i].value+pitchRelease[i].value/5],[pitchStart[i].value/200+0.5, pitchSustain[i].value/200+0.5, pitchEnd[i].value/200+0.5]]}) }); var pitchAttack = Array.fill(4, {|i| NumberBox() .value_(0.1) .scroll_step_(0.1) .clipLo_(0) .mouseOverAction_({helpView.string = "Number box: Attack time of the pitch Envelope in Seconds"}) .action_({ bEnv.layout.index = i; enV[i+6].value = [[0, pitchAttack[i].value/5, pitchAttack[i].value+pitchRelease[i].value/5],[pitchStart[i].value/200+0.5, pitchSustain[i].value/200+0.5, pitchEnd[i].value/200+0.5]]}) }); var pitchRelease = Array.fill(4, {|i| NumberBox() .value_(0.1) .scroll_step_(0.1) .clipLo_(0) .mouseOverAction_({helpView.string = "Number box: Release time of the pitch Envelope in Seconds"}) .action_({ bEnv.layout.index = i; enV[i+6].value = [[0, pitchAttack[i].value/5, pitchAttack[i].value+pitchRelease[i].value/5],[pitchStart[i].value/200+0.5, pitchSustain[i].value/200+0.5, pitchEnd[i].value/200+0.5]]}) }); var oscText2 = Array.fill(4, {|i| Button().states_([[b[i], Color.black, buttonColor[i]]]).maxWidth_(17).maxHeight_(18).mouseOverAction_({helpView.string = "clicking on this button shows pitch envelope of oscillator "++b[i]})}); var pitchInfoText = ["osc", "start", "sustain", "end", "attack", "release"]; var pitchInfoHelp = [ "four oscilltaors with names a, b, c and d", "Start point of the pitch Envelope in percent and relation to the basic frequency", "Sustain point of the pitch Envelope in percent and relation to the basic frequency", "End point of the pitch Envelope in percent and relation to the basic frequency", "Attack time of the pitch Envelope in Seconds", "Release time of the pitch Envelope in Seconds" ]; var pitchInfo = Array.fill(pitchInfoText.size, {|i| StaticText().string_(pitchInfoText[i]).maxHeight_(10).stringColor_(stringColor).mouseOverAction_({helpView.string = pitchInfoHelp[i]})}); var modText = StaticText().string_("a").stringColor_(stringColor).mouseOverAction_({helpView.string = "moudulation formula (only editable in osc view)"}); var pitchLayout = GridLayout.rows( [pitchInfo[0], pitchInfo[1], pitchInfo[2], pitchInfo[3], pitchInfo[4], pitchInfo[5], pitchInfo[6], pitchInfo[7]], [oscText2[0], pitchStart[0], pitchSustain[0], pitchEnd[0], pitchAttack[0], pitchRelease[0], [bEnv, rows: 4]], [oscText2[1], pitchStart[1], pitchSustain[1], pitchEnd[1], pitchAttack[1], pitchRelease[1]], [oscText2[2], pitchStart[2], pitchSustain[2], pitchEnd[2], pitchAttack[2], pitchRelease[2]], [oscText2[3], pitchStart[3], pitchSustain[3], pitchEnd[3], pitchAttack[3], pitchRelease[3]], [[modText, columns:7]] ); var pitchView = View().layout_(pitchLayout).background_(Color.gray(0.2,0.8)); //FXView var panner = NumberBox().minWidth_(40).maxWidth_(50).clipLo_(-1).clipHi_(1).value_(0).scroll_step_(0.1).action_({|value| fx.set(\pos, value.value)}).mouseOverAction_({helpView.string = "Number Box: pans the signal on the left or right speaker. -1 is the left and 1 is the right one"}); var delayTime = NumberBox().clipLo_(0).clipHi_(1).scroll_step_(0.1).value_(0).action_({|value| fx.set(\delayTime, value.value)}).mouseOverAction_({helpView.string = "Delay time in seconds."}); var decayTime = NumberBox().clipLo_(-1).clipHi_(1).scroll_step_(0.1).value_(0.3).action_({|value| fx.set(\decayTime, value.value)}).mouseOverAction_({helpView.string = "Time for the echoes to decay by 60 decibels. If this time is negative then the feedback coefficient will be negative, thus emphasizing only odd harmonics at an octave lower."}); var level = NumberBox().minWidth_(40).maxWidth_(50).clipLo_(0).clipHi_(2).scroll_step_(0.1).value_(1).action_({|value| fx.set(\level, value.value)}).mouseOverAction_({helpView.string = "Master Levelmeter"}); var fxLayout = GridLayout.rows( [StaticText().string_("Envelope").stringColor_(stringColor).minWidth_(70), nil, StaticText().string_("start").stringColor_(stringColor), StaticText().string_("sustain").stringColor_(stringColor), StaticText().string_("end").stringColor_(stringColor), StaticText().string_("attack").stringColor_(stringColor), StaticText().string_("release").stringColor_(stringColor), StaticText().string_("curve").stringColor_(stringColor),nil], [StaticText().string_("lfo").stringColor_(stringColor).minWidth_(70), lfoMenu, lfoStart, lfoSustain, lfoEnd, lfoAttack, lfoRelease, curveBox[4], lfoEnv, StaticText().string_("phase").stringColor_(stringColor), lfoPhase], [StaticText().string_("filter").stringColor_(stringColor).minWidth_(70), filterMenu, filterStart, filterSustain, filterEnd, filterAttack, filterRelease, curveBox[5], filterEnv, StaticText().string_("rq").stringColor_(stringColor), rq], [ nil, StaticText().string_("delayTime").stringColor_(stringColor), StaticText().string_("decay").stringColor_(stringColor) ], [ StaticText().string_("Delay:").stringColor_(stringColor), delayTime, decayTime ] ); var fxView = View().background_(Color.gray(0.2,0.8)).layout_(fxLayout); var stackLayout = StackLayout(oscView,fxView, pitchView); var stackView = View().layout_(stackLayout); //Interaction var lll = String.new;//Zwischenspeicher für ll an iter Stelle var synthBuildFunc = { point.do{|item, i| switch(item.size, 1, {["ll[i].isString: "++ll[i].isString].postln; SynthDef.new(ll[i].asSymbol,{ arg freq, freqMul0, fine0, phase0, mul0, gate=1, lfoIndex = 0, lfoPhase = 0, filterIndex = 0, rq = 1, out; var snd, env, envctl, ampEnv, pitchEnv0, pitchEnvctl0, pitch0, lfoEnv, lfoEnvctl, lfoFreq, lfo, filterEnv, filterEnvctl, filterFreq, filter; env = Env.newClear(4); envctl = \env0.kr(env.asArray); ampEnv = EnvGen.kr(envctl, gate, doneAction: 2); pitchEnv0 = Env.newClear(); pitchEnvctl0 = \pitchEnv0.kr(pitchEnv0.asArray); pitch0 = EnvGen.kr(pitchEnvctl0, gate); lfoEnv = Env.newClear(4); lfoEnvctl = \lfoEnv.kr(lfoEnv.asArray); lfoFreq = EnvGen.kr(lfoEnvctl, gate); lfo = [ SinOsc.ar(0, 0, 0.1, 1) , SinOsc.ar(lfoFreq, lfoPhase), LFTri.ar(lfoFreq, lfoPhase), LFSaw.ar(lfoFreq, lfoPhase)]; filterEnv = Env.newClear(4); filterEnvctl = \filterEnv.kr(filterEnv.asArray); filterFreq = EnvGen.kr( filterEnvctl, gate); if (ll[i] == "WhiteNoise", {snd = ll[i].interpret.ar(mul0)}, {snd = ll[i].interpret.ar(freq*freqMul0+fine0+pitch0, phase0, mul0)}); snd = snd * ampEnv*Select.ar(lfoIndex, lfo); filter = [snd, BPF.ar( snd, filterFreq, rq), RLPF.ar( snd, filterFreq, rq), RHPF.ar( snd, filterFreq, rq)]; snd = Select.ar(filterIndex, filter); Out.ar(out, snd); }).add; }, 3, { lll = ll[i].split($*); SynthDef(l[i].asSymbol, {|freq,freqMul0=1,freqMul1=1,fine0=0,fine1=0, phase0=0, phase1=0, mul0=0.5, mul1=0.5,gate=1, lfoIndex = 0, lfoPhase = 0, filterIndex = 0, rq = 1, out| var snd,snd0, snd1, env0,env1,envctl0,envctl1,ampEnv0,ampEnv1,lfoEnv,lfoEnvctl,lfoFreq,lfo, pitchEnv0, pitchEnvctl0, pitch0, pitchEnv1, pitchEnvctl1, pitch1, filterEnv, filterEnvctl, filterFreq, filter; env0 = Env.newClear(4); envctl0 = \env0.kr(env0.asArray); ampEnv0 = EnvGen.kr(envctl0, gate, doneAction: 2); env1 = Env.newClear(4); envctl1 = \env1.kr(env1.asArray); ampEnv1 = EnvGen.kr(envctl1, gate, doneAction: 2); lfoEnv = Env.newClear(4); lfoEnvctl = \lfoEnv.kr(lfoEnv.asArray); lfoFreq = EnvGen.kr(lfoEnvctl, gate); lfo = [SinOsc.ar(0, 0, 0.1, 1), SinOsc.ar(lfoFreq, lfoPhase), LFTri.ar(lfoFreq, lfoPhase), LFSaw.ar(lfoFreq, lfoPhase)]; pitchEnv0 = Env.newClear(); pitchEnvctl0 = \pitchEnv0.kr(pitchEnv0.asArray); pitch0 = EnvGen.kr(pitchEnvctl0, gate); pitchEnv1 = Env.newClear(); pitchEnvctl1 = \pitchEnv1.kr(pitchEnv1.asArray); pitch1 = EnvGen.kr(pitchEnvctl1, gate); filterEnv = Env.newClear(4); filterEnvctl = \filterEnv.kr(filterEnv.asArray); filterFreq = EnvGen.kr( filterEnvctl, gate); if(lll[0] == "WhiteNoise", {snd0 = lll[0].interpret.ar(mul0);}, {snd0 = lll[0].interpret.ar(freq*freqMul0+fine0+pitch0, phase0, mul0);}); if(lll[1] == "WhiteNoise", {snd1 = lll[1].interpret.ar(mul1);}, {snd1 = lll[1].interpret.ar(freq*freqMul1+fine1+pitch1, phase1, mul1);}); snd0 = snd0 * ampEnv0; snd1 = snd1 * ampEnv1; snd = snd0*snd1*Select.ar(lfoIndex, lfo); filter = [snd, BPF.ar( snd, filterFreq, rq), RLPF.ar( snd, filterFreq, rq), RHPF.ar( snd, filterFreq, rq)]; snd = Select.ar(filterIndex, filter); Out.ar(out, snd); } ).add; }, 5, { lll = ll[i].split($*); SynthDef(l[i].asSymbol, { |freq,freqMul0=1, freqMul1=1, freqMul2 = 1,fine0=0,fine1=0,fine2=0, phase0=0,phase1=0,phase2=0,mul0=0.5,mul1=0.5,mul2=0.5,gate=1, lfoIndex = 0, lfoPhase = 0, filterIndex = 0, rq = 1, out| var snd, snd0,snd1,snd2,env0,env1,env2,envctl0,envctl1,envctl2,ampEnv0,ampEnv1,ampEnv2,lfoEnv,lfoEnvctl,lfoFreq,lfo, pitchEnv0, pitchEnvctl0, pitch0, pitchEnv1, pitchEnvctl1, pitch1, pitchEnv2, pitchEnvctl2, pitch2, filterEnv, filterEnvctl, filterFreq, filter; env0 = Env.newClear(4); envctl0 = \env0.kr(env0.asArray); ampEnv0 = EnvGen.kr(envctl0, gate, doneAction: 2); env1 = Env.newClear(4); envctl1 = \env1.kr(env1.asArray); ampEnv1 = EnvGen.kr(envctl1, gate, doneAction: 2); env2 = Env.newClear(4); envctl2 = \env2.kr(env2.asArray); ampEnv2 = EnvGen.kr(envctl2, gate, doneAction: 2); lfoEnv = Env.newClear(4); lfoEnvctl = \lfoEnv.kr(lfoEnv.asArray); lfoFreq = EnvGen.kr(lfoEnvctl, gate); lfo = [SinOsc.ar(0, 0, 0.1, 1), SinOsc.ar(lfoFreq, lfoPhase), LFTri.ar(lfoFreq, lfoPhase), LFSaw.ar(lfoFreq, lfoPhase)]; pitchEnv0 = Env.newClear(); pitchEnvctl0 = \pitchEnv0.kr(pitchEnv0.asArray); pitch0 = EnvGen.kr(pitchEnvctl0, gate); pitchEnv1 = Env.newClear(); pitchEnvctl1 = \pitchEnv1.kr(pitchEnv1.asArray); pitch1 = EnvGen.kr(pitchEnvctl1, gate); pitchEnv2 = Env.newClear(); pitchEnvctl2 = \pitchEnv2.kr(pitchEnv2.asArray); pitch2 = EnvGen.kr(pitchEnvctl2, gate); filterEnv = Env.newClear(4); filterEnvctl = \filterEnv.kr(filterEnv.asArray); filterFreq = EnvGen.kr( filterEnvctl, gate); if(lll[0] == "WhiteNoise", {snd0 = lll[0].interpret.ar(mul0);}, {snd0 = lll[0].interpret.ar(freq*freqMul0+fine0+pitch0, phase0, mul0);}); if(lll[1] == "WhiteNoise", {snd1 = lll[1].interpret.ar(mul1);}, {snd1 = lll[1].interpret.ar(freq*freqMul1+fine1+pitch1, phase1, mul1);}); if(lll[3] == "WhiteNoise", {snd2 = lll[2].interpret.ar(mul2);}, {snd2 = lll[2].interpret.ar(freq*freqMul2+fine2+pitch2, phase2, mul2);}); snd0 = snd0 * ampEnv0; snd1 = snd1 * ampEnv1; snd2 = snd2 * ampEnv2; snd = snd0*snd1*snd2*Select.ar(lfoIndex, lfo); filter = [snd, BPF.ar( snd, filterFreq, rq), RLPF.ar( snd, filterFreq, rq), RHPF.ar( snd, filterFreq, rq)]; snd = Select.ar(filterIndex, filter); Out.ar(out, snd ) }).add; }, 7, { lll = ll[i].split($*); SynthDef(l[i].asSymbol, { |freq, freqMul0=1, freqMul1=1, freqMul2 = 1, freqMul3 = 1,fine0=0,fine1=0,fine2=0,fine3=0,phase0=0,phase1=0,phase2=0,phase3=0, mul0=0.5,mul1=0.5,mul2=0.5,mul3=0.5, gate=1, lfoIndex = 0, lfoPhase = 0, filterIndex = 0, rq = 0, out| var snd, snd0,snd1,snd2,snd3,env0,env1,env2,env3,envctl0,envctl1,envctl2,envctl3,ampEnv0,ampEnv1,ampEnv2,ampEnv3,lfoEnv,lfoEnvctl,lfoFreq,lfo, pitchEnv0, pitchEnvctl0, pitch0, pitchEnv1, pitchEnvctl1, pitch1, pitchEnv2, pitchEnvctl2, pitch2, pitchEnv3, pitchEnvctl3, pitch3, filterEnv, filterEnvctl, filterFreq, filter; env0 = Env.newClear(4); envctl0 = \env0.kr(env0.asArray); ampEnv0 = EnvGen.kr(envctl0, gate, doneAction: 2); env1 = Env.newClear(4); envctl1 = \env1.kr(env1.asArray); ampEnv1 = EnvGen.kr(envctl1, gate, doneAction: 2); env2 = Env.newClear(4); envctl2 = \env2.kr(env2.asArray); ampEnv2 = EnvGen.kr(envctl2, gate, doneAction: 2); env3 = Env.newClear(4); envctl3 = \env3.kr(env3.asArray); ampEnv3 = EnvGen.kr(envctl3, gate, doneAction: 2); lfoEnv = Env.newClear(4); lfoEnvctl = \lfoEnv.kr(lfoEnv.asArray); lfoFreq = EnvGen.kr(lfoEnvctl, gate); lfo = [SinOsc.ar(0, 0, 0.1, 1), SinOsc.ar(lfoFreq, lfoPhase), LFTri.ar(lfoFreq, lfoPhase), LFSaw.ar(lfoFreq, lfoPhase)]; pitchEnv0 = Env.newClear(); pitchEnvctl0 = \pitchEnv0.kr(pitchEnv0.asArray); pitch0 = EnvGen.kr(pitchEnvctl0, gate); pitchEnv1 = Env.newClear(); pitchEnvctl1 = \pitchEnv1.kr(pitchEnv1.asArray); pitch1 = EnvGen.kr(pitchEnvctl1, gate); pitchEnv2 = Env.newClear(); pitchEnvctl2 = \pitchEnv2.kr(pitchEnv2.asArray); pitch2 = EnvGen.kr(pitchEnvctl2, gate); pitchEnv3 = Env.newClear(); pitchEnvctl3 = \pitchEnv2.kr(pitchEnv3.asArray); pitch3 = EnvGen.kr(pitchEnvctl3, gate); filterEnv = Env.newClear(4); filterEnvctl = \filterEnv.kr(filterEnv.asArray); filterFreq = EnvGen.kr( filterEnvctl, gate); if(lll[0] == "WhiteNoise", {snd0 = lll[0].interpret.ar(mul0)},{snd0 = lll[0].interpret.ar(freq*freqMul0+fine0+pitch0, phase0, mul0)}); if(lll[1] == "WhiteNoise", {snd1 = lll[1].interpret.ar(mul1)},{snd1 = lll[1].interpret.ar(freq*freqMul1+fine1+pitch1, phase1, mul1)}); if(lll[2] == "WhiteNoise", {snd2 = lll[2].interpret.ar(mul2)},{snd2 = lll[2].interpret.ar(freq*freqMul2+fine2+pitch2, phase2, mul2)}); if(lll[3] == "WhiteNoise", {snd3 = lll[3].interpret.ar(mul3)},{snd3 = lll[3].interpret.ar(freq*freqMul3+fine3+pitch3, phase3, mul3)}); snd0 = snd0 * ampEnv0; snd1 = snd1 * ampEnv1; snd2 = snd2 * ampEnv2; snd3 = snd3 * ampEnv3; snd = snd0*snd1*snd2*snd3*Select.ar(lfoIndex, lfo); filter = [snd, BPF.ar( snd, filterFreq, rq), RLPF.ar( snd, filterFreq, rq), RHPF.ar( snd, filterFreq, rq)]; snd = Select.ar(filterIndex, filter); Out.ar(out, snd); } ).add; } ); }; }; /* var fx; var fxSynth = { SynthDef.new(\masterFX, { arg input, pos = 0, delayTime = 0, decayTime = 0, level = 1; var in, snd, fb, delay, left, right, locIn; in = In.ar(input,1); locIn = LocalIn.ar(1, 0); snd = locIn + in; fb = DelayC.ar(snd*decayTime, 1, delayTime); LocalOut.ar( fb ); snd = Balance2.ar(snd, snd, pos, level); Out.ar(0, snd); }).add; fx = Synth.new(\masterFX, [\input, ~out]); }; */ var point; var points; var l = String.new; var ll = String.new; var z = (); var playDownFunc = {|note| ll.postln; z[note] = Array.newClear(l.size); l.do{|item,i| switch(point[i].size, 1, { z[note][i] = Synth(item.asSymbol, [ \freq, freqBox.value, \freqMul0, harmBox[b.find([point[i]])].value, \fine0, fineBox[b.find([point[i]])].value, \phase0, phaseBox[b.find([point[i]])].value, \mul0, ampBox[b.find([point[i]])].value, \env0, Env( [0,peakBox[b.find([point[i]])].value, sustainBox[b.find([point[i]])].value, 0], [attackBox[b.find([point[i]])].value, decayBox[b.find([point[i]])].value, releaseBox[b.find([point[i]])].value], curveBox[b.find([point[i]])].value, releaseNode:2 ), \pitchEnv0, Env( [pitchStart[b.find([point[i]])].value/100*freqBox.value,pitchSustain[b.find([point[i]])].value/100*freqBox.value,pitchEnd[b.find([point[i]])].value/100*freqBox.value], [pitchAttack[b.find([point[i]])].value,pitchRelease[b.find([point[i]])].value], releaseNode: 1), \lfoEnv, Env([lfoStart.value,lfoSustain.value,lfoRelease.value],[lfoAttack.value,lfoRelease.value], curveBox[4].value, 1), \lfoIndex, lfoMenu.value, \filterEnv, Env([filterStart.value/100*freqBox.value+freqBox.value,filterSustain.value/100*freqBox.value+freqBox.value,filterEnd.value/100*freqBox.value+freqBox.value],[filterAttack.value,filterRelease.value], curveBox[5].value, 1), \filterIndex, filterMenu.value, \lfoPhase, lfoPhase.value, \rq, rq.value, \out, ~out ]); }, 3, { points = point[i].split($*); z[note][i] = Synth(item.asSymbol, [ \freq, freqBox.value, \freqMul0, harmBox[b.find([points[0]])].value, \freqMul1, harmBox[b.find([points[1]])].value, \fine0, fineBox[b.find([points[0]])].value, \fine1, fineBox[b.find([points[1]])].value, \phase0, phaseBox[b.find([points[0]])].value, \phase1, phaseBox[b.find([points[1]])].value, \mul0, ampBox[b.find([points[0]])].value, \mul1, ampBox[b.find([points[1]])].value, \env0, Env( [0,peakBox[b.find([points[0]])].value, sustainBox[b.find([points[0]])].value, 0], [attackBox[b.find([points[0]])].value, decayBox[b.find([points[0]])].value, releaseBox[b.find([points[0]])].value], curveBox[b.find([points[0]])].value, releaseNode:2 ), \env1, Env( [0,peakBox[b.find([points[1]])].value, sustainBox[b.find([points[1]])].value, 0], [attackBox[b.find([points[1]])].value, decayBox[b.find([points[1]])].value, releaseBox[b.find([points[1]])].value], curveBox[b.find([points[1]])].value, releaseNode:2 ), \pitchEnv0, Env( [pitchStart[b.find([points[0]])].value/100*freqBox.value,pitchSustain[b.find([points[0]])].value/100*freqBox.value,pitchEnd[b.find([points[0]])].value/100*freqBox.value], [pitchAttack[b.find([points[0]])].value,pitchRelease[b.find([points[0]])].value], releaseNode: 1), \pitchEnv1, Env( [pitchStart[b.find([points[1]])].value/100*freqBox.value,pitchSustain[b.find([points[1]])].value/100*freqBox.value,pitchEnd[b.find([points[1]])].value/100*freqBox.value], [pitchAttack[b.find([points[1]])].value,pitchRelease[b.find([points[1]])].value], releaseNode: 1), \lfoEnv, Env([lfoStart.value,lfoSustain.value,lfoRelease.value],[lfoAttack.value,lfoRelease.value], curveBox[4].value, 1), \lfoIndex, lfoMenu.value, \filterEnv, Env([filterStart.value+freqBox.value,filterSustain.value+freqBox.value,filterEnd.value+freqBox.value],[filterAttack.value,filterRelease.value], curveBox[5].value, 1), \filterIndex, filterMenu.value, \lfoPhase, lfoPhase.value, \rq, rq.value, \out, ~out ]); }, 5, { points = point[i].split($*); z[note][i] = Synth(item.asSymbol, [ \freq, freqBox.value, \freqMul0, harmBox[b.find([points[0]])].value, \freqMul1, harmBox[b.find([points[1]])].value, \freqMul2, harmBox[b.find([points[2]])].value, \fine0, fineBox[b.find([points[0]])].value, \fine1, fineBox[b.find([points[1]])].value, \fine2, fineBox[b.find([points[2]])].value, \phase0, phaseBox[b.find([points[0]])].value, \phase1, phaseBox[b.find([points[1]])].value, \phase2, phaseBox[b.find([points[2]])].value, \mul0, ampBox[b.find([points[0]])].value, \mul1, ampBox[b.find([points[1]])].value, \mul2, ampBox[b.find([points[2]])].value, \env0, Env( [0,peakBox[b.find([points[0]])].value, sustainBox[b.find([points[0]])].value, 0], [attackBox[b.find([points[0]])].value, decayBox[b.find([points[0]])].value, releaseBox[b.find([points[0]])].value], curveBox[b.find([points[0]])].value, releaseNode:2 ), \env1, Env( [0,peakBox[b.find([points[1]])].value, sustainBox[b.find([points[1]])].value, 0], [attackBox[b.find([points[1]])].value, decayBox[b.find([points[1]])].value, releaseBox[b.find([points[1]])].value], curveBox[b.find([points[1]])].value, releaseNode:2 ), \env2, Env( [0,peakBox[b.find([points[2]])].value, sustainBox[b.find([points[2]])].value, 0], [attackBox[b.find([points[2]])].value, decayBox[b.find([points[2]])].value, releaseBox[b.find([points[2]])].value], curveBox[b.find([points[2]])].value, releaseNode:2 ), \pitchEnv0, Env( [pitchStart[b.find([points[0]])].value/100*freqBox.value,pitchSustain[b.find([points[0]])].value/100*freqBox.value,pitchEnd[b.find([points[0]])].value/100*freqBox.value], [pitchAttack[b.find([points[0]])].value,pitchRelease[b.find([points[0]])].value], releaseNode: 1), \pitchEnv1, Env( [pitchStart[b.find([points[1]])].value/100*freqBox.value,pitchSustain[b.find([points[1]])].value/100*freqBox.value,pitchEnd[b.find([points[1]])].value/100*freqBox.value], [pitchAttack[b.find([points[1]])].value,pitchRelease[b.find([points[1]])].value], releaseNode: 1), \pitchEnv2, Env( [pitchStart[b.find([points[2]])].value/100*freqBox.value,pitchSustain[b.find([points[2]])].value/100*freqBox.value,pitchEnd[b.find([points[2]])].value/100*freqBox.value], [pitchAttack[b.find([points[2]])].value,pitchRelease[b.find([points[2]])].value], releaseNode: 1), \lfoEnv, Env([lfoStart.value,lfoSustain.value,lfoRelease.value],[lfoAttack.value,lfoRelease.value], curveBox[4].value, 1), \lfoIndex, lfoMenu.value, \filterEnv, Env([filterStart.value+freqBox.value,filterSustain.value+freqBox.value,filterEnd.value+freqBox.value],[filterAttack.value,filterRelease.value], curveBox[5].value, 1), \filterIndex, filterMenu.value, \lfoPhase, lfoPhase.value, \rq, rq.value, \out, ~out ]); }, 7, { points = point[i].split($*); z[note][i] = Synth(item.asSymbol, [ \freq, freqBox.value, \freqMul0, harmBox[b.find([points[0]])].value, \freqMul1, harmBox[b.find([points[1]])].value, \freqMul2, harmBox[b.find([points[2]])].value, \freqMul3, harmBox[b.find([points[3]])].value, \fine0, fineBox[b.find([points[0]])].value, \fine1, fineBox[b.find([points[1]])].value, \fine2, fineBox[b.find([points[2]])].value, \fine3, fineBox[b.find([points[3]])].value, \phase0, phaseBox[b.find([points[0]])].value, \phase1, phaseBox[b.find([points[1]])].value, \phase2, phaseBox[b.find([points[2]])].value, \phase3, phaseBox[b.find([points[3]])].value, \mul0, ampBox[b.find([points[0]])].value, \mul1, ampBox[b.find([points[1]])].value, \mul2, ampBox[b.find([points[2]])].value, \mul3, ampBox[b.find([points[3]])].value, \env0, Env( [0,peakBox[b.find([points[0]])].value, sustainBox[b.find([points[0]])].value, 0], [attackBox[b.find([points[0]])].value, decayBox[b.find([points[0]])].value, releaseBox[b.find([points[0]])].value], curveBox[b.find([points[0]])].value, releaseNode:2 ), \env1, Env( [0,peakBox[b.find([points[1]])].value, sustainBox[b.find([points[1]])].value, 0], [attackBox[b.find([points[1]])].value, decayBox[b.find([points[1]])].value, releaseBox[b.find([points[1]])].value], curveBox[b.find([points[1]])].value, releaseNode:2 ), \env2, Env( [0,peakBox[b.find([points[2]])].value, sustainBox[b.find([points[2]])].value, 0], [attackBox[b.find([points[2]])].value, decayBox[b.find([points[2]])].value, releaseBox[b.find([points[2]])].value], curveBox[b.find([points[2]])].value, releaseNode:2 ), \env3, Env( [0,peakBox[b.find([points[3]])].value, sustainBox[b.find([points[3]])].value, 0], [attackBox[b.find([points[3]])].value, decayBox[b.find([points[3]])].value, releaseBox[b.find([points[3]])].value], curveBox[b.find([points[3]])].value, releaseNode:2 ), \pitchEnv0, Env( [pitchStart[b.find([points[0]])].value/100*freqBox.value,pitchSustain[b.find([points[0]])].value/100*freqBox.value,pitchEnd[b.find([points[0]])].value/100*freqBox.value], [pitchAttack[b.find([points[0]])].value,pitchRelease[b.find([points[0]])].value], releaseNode: 1), \pitchEnv1, Env( [pitchStart[b.find([points[1]])].value/100*freqBox.value,pitchSustain[b.find([points[1]])].value/100*freqBox.value,pitchEnd[b.find([points[1]])].value/100*freqBox.value], [pitchAttack[b.find([points[1]])].value,pitchRelease[b.find([points[1]])].value], releaseNode: 1), \pitchEnv2, Env( [pitchStart[b.find([points[2]])].value/100*freqBox.value,pitchSustain[b.find([points[2]])].value/100*freqBox.value,pitchEnd[b.find([points[2]])].value/100*freqBox.value], [pitchAttack[b.find([points[2]])].value,pitchRelease[b.find([points[2]])].value], releaseNode: 1), \pitchEnv3, Env( [pitchStart[b.find([points[3]])].value/100*freqBox.value,pitchSustain[b.find([points[3]])].value/100*freqBox.value,pitchEnd[b.find([points[3]])].value/100*freqBox.value], [pitchAttack[b.find([points[3]])].value,pitchRelease[b.find([points[3]])].value], releaseNode: 1), \lfoEnv, Env([lfoStart.value,lfoSustain.value,lfoRelease.value],[lfoAttack.value,lfoRelease.value], curveBox[4].value, 1), \lfoIndex, lfoMenu.value, \filterEnv, Env([filterStart.value+freqBox.value,filterSustain.value+freqBox.value,filterEnd.value+freqBox.value],[filterAttack.value,filterRelease.value], curveBox[5].value, 1), \filterIndex, filterMenu.value, \lfoPhase, lfoPhase.value, \rq, rq.value, \out, ~out ]); } ); }; }; var playUpFunc = {|note| z.removeAt(note).do{|synth| synth.release}; }; Server.default.sync; ~out = Bus.audio(s,1); modField.action_({|s| l = String.new; point = String.new; s.value.do{|item, i| switch(item.asString, "a", { switch(waveformMenu[0].value, 0, {l = l ++ "SinOsc"}, 1, {l = l ++ "LFTri"}, 2, {l = l ++ "LFSaw"}, 3, {l = l ++ "WhiteNoise"} ); }, "b", { switch(waveformMenu[1].value, 0, {l = l ++ "SinOsc"}, 1, {l = l ++ "LFTri"}, 2, {l = l ++ "LFSaw"}, 3, {l = l ++ "WhiteNoise"} ); }, "c", { switch(waveformMenu[2].value, 0, {l = l ++ "SinOsc"}, 1, {l = l ++ "LFTri"}, 2, {l = l ++ "LFSaw"}, 3, {l = l ++ "WhiteNoise"} ); }, "d", { switch(waveformMenu[3].value, 0, {l = l ++ "SinOsc"}, 1, {l = l ++ "LFTri"}, 2, {l = l ++ "LFSaw"}, 3, {l = l ++ "WhiteNoise"} ); }, "+", {l = l ++ "+"}, "*", {l = l ++ "*"} ); }; ll = l.split($+); l = l.replace("*", "").split($+); ["SynthName/item/variableName: "++ l].postln; point = s.value.split($+); ["point: "++ point].postln; modText.string = s.value; synthBuildFunc.value; }); Server.default.sync; oscButton.value = 1; //oscEnv Interaction for(0,3,{|i| harmBox[i].mouseDownAction_({aEnv.layout.index_(i);}); fineBox[i].mouseDownAction_({aEnv.layout.index_(i);}); ampBox[i].mouseDownAction_({aEnv.layout.index_(i);}); phaseBox[i].mouseDownAction_({aEnv.layout.index_(i);}); waveformMenu[i].mouseDownAction_({aEnv.layout.index_(i);}); oscText[i].mouseDownAction_({aEnv.layout.index_(i);}); oscShow1[i].mouseDownAction_({aEnv.layout.index_(i);}); oscShow2[i].mouseDownAction_({aEnv.layout.index_(i);}); }); play.mouseDownAction_(playDownFunc).mouseUpAction_(playUpFunc); w.layout_(GridLayout.rows( [modus, columns: 7], [[stackView, columns: 7]], [play,info.last,freqBox, StaticText().string_("pan").stringColor_(stringColor), panner, StaticText().string_("level").stringColor_(stringColor), level ] )); w.background_(Color.gray(0.2,0.9)); w.front; modField.valueAction_(modField.value); fxSynth.value; Server.default.sync; decayTime.valueAction = 0.5; decayTime.valueAction = decayTime.value; w.onClose_({fx.free}); ///////KEYS/MIDI // looks like I'll need to change some of this to have it play how I want it to. keyDict.putPairs([\z, true, \x, true, \c, true, \v, true, \b, true, \n, true, \m, true, \a, true, \s, true, \s, true, \d, true, \f, true, \g, true, \h, true, \j, true, \k, true, \l, true, \q, true, \w, true, \e, true, \r, true, \t, true, \y, true, \u, true, \i, true, \o, true, \p, true, \1, true, \2, true, \3, true, \4, true, \5, true, \6, true, \7, true, \8, true, \9, true, \0, true]); w.view.keyDownAction_({|view, char| switch(char, $z, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-12).midicps; playDownFunc.(1); keyDict.putPairs([\z, false]);}, {nil})}, $x, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-11).midicps; playDownFunc.(2); keyDict.putPairs([\x, false]);}, {nil})}, $c, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-10).midicps; playDownFunc.(3); keyDict.putPairs([\c, false]);}, {nil})}, $v, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-9).midicps; playDownFunc.(4); keyDict.putPairs([\v, false]);}, {nil})}, $b, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-8).midicps; playDownFunc.(5); keyDict.putPairs([\b, false]);}, {nil})}, $n, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-7).midicps; playDownFunc.(6); keyDict.putPairs([\n, false]);}, {nil})}, $a, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-7).midicps; playDownFunc.(7); keyDict.putPairs([\a, false]);}, {nil})}, $m, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-6).midicps; playDownFunc.(8); keyDict.putPairs([\m, false]);}, {nil})}, $s, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-6).midicps; playDownFunc.(9); keyDict.putPairs([\s, false]);}, {nil})}, $d, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-5).midicps; playDownFunc.(10); keyDict.putPairs([\d, false]);}, {nil})}, $f, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-4).midicps; playDownFunc.(11); keyDict.putPairs([\f, false]);}, {nil})}, $g, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-3).midicps; playDownFunc.(12); keyDict.putPairs([\g, false]);}, {nil})}, $h, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-2).midicps; playDownFunc.(13); keyDict.putPairs([\h, false]);}, {nil})}, $q, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-2).midicps; playDownFunc.(14); keyDict.putPairs([\q, false]);}, {nil})}, $j, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-1).midicps; playDownFunc.(15); keyDict.putPairs([\j, false]);}, {nil})}, $w, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct-1).midicps; playDownFunc.(16); keyDict.putPairs([\w, false]);}, {nil})}, $k, { if(keyDict.at( char.asSymbol), {freqBox.value = oct.midicps; playDownFunc.(17); keyDict.putPairs([\k, false]);}, {nil})}, $e, { if(keyDict.at( char.asSymbol), {freqBox.value = oct.midicps; playDownFunc.(18); keyDict.putPairs([\e, false]);}, {nil})}, $l, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+1).midicps; playDownFunc.(19); keyDict.putPairs([\l, false]);}, {nil})}, $r, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+1).midicps; playDownFunc.(20); keyDict.putPairs([\r, false]);}, {nil})}, $t, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+2).midicps; playDownFunc.(21); keyDict.putPairs([\t, false]);}, {nil})}, $y, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+3).midicps; playDownFunc.(22); keyDict.putPairs([\y, false]);}, {nil})}, $1, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+3).midicps; playDownFunc.(23); keyDict.putPairs([\1, false]);}, {nil})}, $u, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+4).midicps; playDownFunc.(24); keyDict.putPairs([\u, false]);}, {nil})}, $2, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+4).midicps; playDownFunc.(25); keyDict.putPairs([\2, false]);}, {nil})}, $i, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+5).midicps; playDownFunc.(26); keyDict.putPairs([\i, false]);}, {nil})}, $3, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+5).midicps; playDownFunc.(27); keyDict.putPairs([\3, false]);}, {nil})}, $o, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+6).midicps; playDownFunc.(28); keyDict.putPairs([\o, false]);}, {nil})}, $4, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+6).midicps; playDownFunc.(29); keyDict.putPairs([\4, false]);}, {nil})}, $p, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+7).midicps; playDownFunc.(30); keyDict.putPairs([\p, false]);}, {nil})}, $5, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+7).midicps; playDownFunc.(31); keyDict.putPairs([\5, false]);}, {nil})}, $6, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+8).midicps; playDownFunc.(32); keyDict.putPairs([\6, false]);}, {nil})}, $7, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+9).midicps; playDownFunc.(33); keyDict.putPairs([\7, false]);}, {nil})}, $8, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+10).midicps; playDownFunc.(34); keyDict.putPairs([\8, false]);}, {nil})}, $9, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+11).midicps; playDownFunc.(35); keyDict.putPairs([\9, false]);}, {nil})}, $0, { if(keyDict.at( char.asSymbol), {freqBox.value = (oct+12).midicps; playDownFunc.(36); keyDict.putPairs([\0, false]);}, {nil})}, $,, {oct = oct - 12}, $., {oct = oct + 12} ); char.asString.postln; }); w.view.keyUpAction_({|view, char| switch(char, $z, {playUpFunc.(1); keyDict.putPairs([\z, true]);}, $x, {playUpFunc.(2); keyDict.putPairs([\x, true]);}, $c, {playUpFunc.(3); keyDict.putPairs([\c, true]);}, $v, {playUpFunc.(4); keyDict.putPairs([\v, true])}, $b, {playUpFunc.(5); keyDict.putPairs([\b, true])}, $n, {playUpFunc.(6); keyDict.putPairs([\n, true])}, $a, {playUpFunc.(7); keyDict.putPairs([\a, true])}, $m, {playUpFunc.(8); keyDict.putPairs([\m, true])}, $s, {playUpFunc.(9); keyDict.putPairs([\s, true])}, $d, {playUpFunc.(10); keyDict.putPairs([\d, true])}, $f, {playUpFunc.(11); keyDict.putPairs([\f, true])}, $g, {playUpFunc.(12); keyDict.putPairs([\g, true])}, $h, {playUpFunc.(13); keyDict.putPairs([\h, true])}, $q, {playUpFunc.(14); keyDict.putPairs([\q, true])}, $j, {playUpFunc.(15); keyDict.putPairs([\j, true])}, $w, {playUpFunc.(16); keyDict.putPairs([\w, true])}, $k, {playUpFunc.(17); keyDict.putPairs([\k, true])}, $e, {playUpFunc.(18); keyDict.putPairs([\e, true])}, $l, {playUpFunc.(19); keyDict.putPairs([\l, true])}, $r, {playUpFunc.(20); keyDict.putPairs([\r, true])}, $t, {playUpFunc.(21); keyDict.putPairs([\t, true])}, $y, {playUpFunc.(22); keyDict.putPairs([\y, true])}, $1, {playUpFunc.(23); keyDict.putPairs([\1, true])}, $u, {playUpFunc.(24); keyDict.putPairs([\u, true])}, $2, {playUpFunc.(25); keyDict.putPairs([\2, true])}, $i, {playUpFunc.(26); keyDict.putPairs([\i, true])}, $3, {playUpFunc.(27); keyDict.putPairs([\3, true])}, $o, {playUpFunc.(28); keyDict.putPairs([\o, true])}, $4, {playUpFunc.(29); keyDict.putPairs([\4, true])}, $p, {playUpFunc.(30); keyDict.putPairs([\p, true])}, $5, {playUpFunc.(31); keyDict.putPairs([\5, true])}, $6, {playUpFunc.(32); keyDict.putPairs([\6, true])}, $7, {playUpFunc.(33); keyDict.putPairs([\7, true])}, $8, {playUpFunc.(34); keyDict.putPairs([\8, true])}, $9, {playUpFunc.(35); keyDict.putPairs([\9, true])}, $0, {playUpFunc.(36); keyDict.putPairs([\0, true])}, ); }); MIDIdef.noteOn(\on, { |vel, note| { freqBox.value = note.midicps; playDownFunc.(note); }.defer }); MIDIdef.noteOff(\off, { |vel, note| { playUpFunc.(note); }.defer }); }); );