{
   "ancestor_list" : [],
   "description" : "I developed this to help me work on hearing and playing in just intonation. It's my first GUI so feedback is very welcome, but it works basically ok for what I want it to!",
   "author" : "jordanwhitede",
   "name" : "GUI to generate scale- and arpeggio-like fragments in Just Intonation",
   "is_private" : null,
   "id" : "1-5ep",
   "code" : "/*\r\n\r\nSimple GUI to generate scale and arpeggio segments of an overtone row above a given fundamental. This is the first GUI I've programmed, so it's certainly not perfect: most notably, all the numbers have to be typed into the boxes before the pattern will run. Feel free to contact me if you have any questions or feedback!\r\n\r\nFor non-experienced users: click in row 9 where it says \"click here\" and press CTRL+ENTER. Start with low volume to be safe :)\r\n\r\n*/\r\n\r\n( // click here\r\ns.waitForBoot({ // GUI\r\n\r\n\r\nvar numButtons = 4;\r\nvar numSliders = 5;\r\nvar numNumberBoxes = 3;\r\nvar numLabels0 = 5;\r\nvar numLabels1 = 3;\r\nvar buttons, sliders, numberBoxes, labels0, labels1, sliderLayout, buttonLayout, numberBoxesLayout, labelsLayout0, labelsLayout1, layout, menu;\r\n\r\nWindow.closeAll;\r\nw = Window.new;\r\n\r\n// objects\r\n\r\nbuttons = numButtons.collect{\r\n\tButton.new\r\n};\r\n\r\nsliders = numSliders.collect{\r\n\tSlider.new.orientation_(\\horizontal)\r\n};\r\n\r\nnumberBoxes = numNumberBoxes.collect{\r\n\tNumberBox.new\r\n};\r\n\r\nlabels0 = numLabels0.collect{\r\n\tStaticText.new\r\n};\r\n\r\nlabels1 = numLabels1.collect{\r\n\tStaticText.new\r\n};\r\n\r\nmenu = PopUpMenu.new;\r\n\r\n// layout\r\n\r\nbuttonLayout = HLayout.new(*buttons);\r\nsliderLayout = VLayout.new(*sliders);\r\nnumberBoxesLayout = HLayout.new(*numberBoxes);\r\nlabelsLayout0 = VLayout.new(*labels0);\r\nlabelsLayout1 = HLayout.new(*labels1);\r\n\r\n//layout = VLayout(sliderLayout, buttonLayout, numberBoxesLayout);\r\nlayout = VLayout(HLayout(labelsLayout0, sliderLayout), HLayout(buttonLayout, menu), VLayout(numberBoxesLayout, labelsLayout1));\r\n\r\n\r\n// sliders\r\n\r\n// Slider 0 - change dur\r\nsliders[0].action_({|obj|\r\n\tvar val = obj.value;\r\n\r\n\t// Scale duration, make sure it is not zero\r\n\tval = val.linlin(0.0, 1.0, 2.0, 0.1);\r\n\t~dur = val;\r\n\tPdefn(\\pDur, ~dur)\r\n});\r\n\r\n// Slider 1 - change atk\r\nsliders[1].action_({|obj|\r\n\tvar val = obj.value;\r\n\tval = val.linlin(0.0, 1.0, 0.01, 0.3);\r\n\t~atk = val;\r\n\tPdefn(\\pAtk, ~atk)\r\n});\r\n\r\n// Slider 2 - change rel\r\nsliders[2].action_({|obj|\r\n\tvar val = obj.value;\r\n\tval = val.linlin(0.0, 1.0, 0.5, 10);\r\n\t~rel = val;\r\n\r\n\tPdefn(\\pRel, ~rel)\r\n});\r\n\r\n// Slider 3 - change amp\r\nsliders[3].action_({|obj|\r\n\tvar val = obj.value;\r\n\tval = val.linlin(0.0, 1.0, 0.0, 0.75);\r\n\t~amp = val;\r\n\tPdefn(\\pAmp, ~amp)\r\n});\r\n\r\n// Slider 4 - change bass amp\r\n~slider4 = sliders[4].action_({|obj|\r\n\tvar bassAmp = obj.value;\r\n\tbassAmp = bassAmp.linlin(0.0, 1.0, 0.05, 0.75);\r\n\t~bassAmp = bassAmp;\r\n\t//x.set(\\amp, bassAmp);\r\n\tif(\r\n\t\tx.isPlaying,\r\n\t\t{x.set(\\amp, ~bassAmp)}\r\n\t)\r\n});\r\n\r\n// numberBoxes\r\n\r\nnumberBoxes[0].value_(55)\r\n.clipLo_(30)\r\n.clipHi_(120)\r\n.action_({\r\n\targ obj; var val;\r\n\tval = obj.value;\r\n\t~fundamental = val;\r\n\tPdefn(\\fundamental, ~fundamental);\r\n\t//x.set(\\fundamental, ~fundamental);\r\n\tif(\r\n\t\tx.isPlaying,\r\n\t\t{x.set(\\fundamental, ~fundamental)}\r\n\t)\r\n})\r\n\r\n;\r\n\r\nnumberBoxes[1].value_(10)\r\n.step_(1)\r\n.clipLo_(5)\r\n.clipHi_(30)\r\n.action_({\r\n\targ obj;\r\n\tvar val = obj.value;\r\n\t~startPartial = val;\r\n\tPdefn(\\startPartial, ~startPartial)\r\n});\r\n\r\nnumberBoxes[2].value_(5)\r\n.step_(1)\r\n.clipLo_(2)\r\n.clipHi_(30)\r\n.action_({\r\n\targ obj;\r\n\tvar val = obj.value;\r\n\t~numNotes = val;\r\n\tPdefn(\\numNotes, ~numNotes)\r\n});\r\n\r\n// buttons\r\n\r\n// Start pattern\r\nbuttons[0].states_([[\"Start Pattern\", Color.black, Color.gray]]).action_({|obj|\r\n\tPbindef(\\pattern).play;\r\n\ty = Synth(\\reverb, [\\in, ~reverbBus]);\r\n});\r\n\r\n\r\n// Stop pattern\r\nbuttons[1].states_([[\"Stop Pattern\", Color.black, Color.gray]]).action_({|obj|\r\n\tPbindef(\\pattern).stop;\r\n\ty.free;\r\n});\r\n\r\n\r\n// Start bass note - to do, try out pmono\r\nbuttons[2].states_([[\"Start Bass Note\", Color.black, Color.gray]]).action_({|obj|\r\n\tx = Synth(\\bass, [\\fundamental, ~fundamental.value, \\amp, ~slider4.value]).register\r\n});\r\n\r\n\r\n// Stop bass note\r\nbuttons[3].states_([[\"Stop Bass Note\", Color.black, Color.gray]]).action_({|obj|\r\n\tx.free;\r\n});\r\n\r\n// Scale or arpeggio\r\n/*\r\nbuttons[4].states_([[\"Scale\", Color.black, Color.gray], [\"Arpeggio\", Color.black, Color.gray]]).action_({\r\n\t|obj| var val;\r\n\tval = obj.value;\r\n\t~step = val + 1;\r\n\tPdefn(\\step, ~step)\r\n\r\n});\r\n*/\r\n\r\n// popup menu\r\n\r\nmenu.items_([\"Scale ascending\", \"Scale descending\", \"Small Arpeggio ascending\", \"Small Arpeggio descending\", \"Big Arpeggio ascending\", \"Big Arpeggio descending\"])\r\n.action_(\r\n\t{\r\n\t\targ menu;\r\n\t\tvar val = menu.value;\r\n\t\tcase\r\n\t\t{val == 0} {~step = 1}\r\n\t\t{val == 1} {~step = -1}\r\n\t\t{val == 2} {~step = 2}\r\n\t\t{val == 3} {~step = -2}\r\n\t\t{val == 4} {~step = 3}\r\n\t\t{val == 5} {~step= -3};\r\n\t\tPdefn(\\step, ~step);\r\n\t}\r\n);\r\n\r\n// labels - fund, bass amp, start partial, num notes\r\n\r\nlabels0[0].string_(\"Speed\");\r\nlabels0[1].string_(\"Attack\");\r\nlabels0[2].string_(\"Release\");\r\nlabels0[3].string_(\"Volume\");\r\nlabels0[4].string_(\"Bass Volume\");\r\nlabels1[0].string_(\"Fundamental\");\r\nlabels1[1].string_(\"Start Partial\");\r\nlabels1[2].string_(\"Scale Length\");\r\n\r\n\r\n// tidying up\r\n\r\nw.layout = layout;\r\nw.front;\r\n\r\n\r\n\r\n// reverb\r\n\r\n~reverbBus = Bus.alloc(\\audio, s, 2);\r\n\r\n\r\nSynthDef(\\reverb, {\r\n\targ in=0, out=0;\r\n\tvar sig;\r\n\r\n\tsig = In.ar(in, 2);\r\n\tsig = FreeVerb.ar(sig);\r\n\tOut.ar(out, sig);\r\n}).add;\r\n\r\n\r\n\r\n// sounds\r\n\r\n\r\nSynthDef(\\blip, {\r\n\targ fundamental=55, ratio=10, amp=0.25, pan=0, atk=0.02, rel=0.1, out=0;\r\n\tvar sig, env;\r\n\r\n\tenv = Env.perc(atk, rel);\r\n\tenv = EnvGen.ar(env, doneAction: 2);\r\n\r\n\tsig = SinOsc.ar(fundamental.lag(0.5) * ratio);\r\n\tsig = sig * env * amp.lag(0.5);\r\n\tsig = Pan2.ar(sig, pan);\r\n\t//sig = FreeVerb.ar(sig);\r\n\t//sig = HPF.ar(sig, 30);\r\n\t//DetectSilence.ar(sig, doneAction: 2);\r\n\tOut.ar(out, sig);\r\n}).add;\r\n\r\n\r\n\r\n\r\nSynthDef(\\bass, {\r\n\targ fundamental=55, amp=0.25, pan=0, out=0, lfo=0.1, lpf=1000;\r\n\tvar sig, moog;\r\n\r\n\tmoog = LFNoise1.ar(lfo).exprange(200, 4000);\r\n\r\n\tsig = LFSaw.ar(fundamental.lag(0.5));\r\n\tsig = MoogFF.ar(sig, moog);\r\n\tsig = LPF.ar(sig, lpf);\r\n\tsig = sig * amp.lag(0.5);\r\n\tsig = Pan2.ar(sig, pan);\r\n\tsig = FreeVerb.ar(sig);\r\n\r\n\tOut.ar(out, sig);\r\n}).add;\r\n\r\n// basic pattern to control\r\n\r\n\r\nPbindef(\\pattern,\r\n\r\n\t\\instrument, \\blip,\r\n\t\\dur, Pdefn(\\pDur),\r\n\t\\ratio, Pseq([Pseries(Pdefn(\\startPartial).asStream, Pdefn(\\step), Pdefn(\\numNotes).asStream)], inf),\r\n\t\\fundamental, Pdefn(\\fundamental),\r\n\t\\amp, Pdefn(\\pAmp),\r\n\t\\atk, Pdefn(\\pAtk),\r\n\t\\rel, Pdefn(\\pRel),\r\n\t\\pan, 0,\r\n\t//\\out, 0\r\n\t\\out, ~reverbBus\r\n);\r\n\r\n// variables initial values\r\n\r\n~dur = 1.0;\r\n~atk = 0.05;\r\n~rel = 0.1;\r\n~amp = 0.25;\r\n~bassAmp = 0.3;\r\n~fundamental = 55;\r\n~startPartial = 10;\r\n~numNotes = 5;\r\n~step = 1;\r\n\r\n};\r\n);\r\n)",
   "labels" : [
      "gui",
      "just intonation"
   ]
}
