{
   "id" : "1-4Uu",
   "is_private" : null,
   "code" : "// ************************************\r\n// Additive Synthesis Demo (GUI)\r\n// Patch 1 - Harmonic Series\r\n// Bruno Ruviaro, 2013-07-22\r\n// ************************************\r\n\r\n/*\r\n\r\nSimple button grid to play first 16 partials of a harmonic series:\r\n\r\n01 02 03 04\r\n05 06 07 08\r\n09 10 11 12\r\n13 14 15 16\r\n\r\nHorizontal Sliders control ADSR envelope.\r\n\r\nAll partials have equal amplitude.\r\n\r\nHow to start: select all (ctrl + A), then evaluate (ctrl + enter)\r\n(on a Mac, use the command key instead of control)\r\n\r\n*/\r\n\r\ns.waitForBoot({\r\n\r\n\tvar win, buttonArray, notesArray, attackSlider, decaySlider, sustainSlider, releaseSlider, volumeSlider, att = 0.01, dec = 0.3, sus = 0.5, rel = 1.0, masterOut = 0.1, fundamental = 110;\r\n\r\n\tnotesArray = Array.newClear(128);\r\n\r\n\tWindow.closeAll;\r\n\r\n\twin = Window.new(\"Additive Synthesis - Harmonic Series\", Rect(500, 100, 400, 590)).front;\r\n\twin.background = Color.grey;\r\n\twin.alpha = 0.95;\r\n\r\n\twin.onClose = {s.freeAll; \"Done!\".postln};\r\n\tCmdPeriod.doOnce({win.close});\r\n\r\n\twin.view.decorator = FlowLayout(win.view.bounds, margin: 10@10, gap: 20@10 );\r\n\r\n\tbuttonArray = Array.fill(16, {Button(win.view, 80@80)});\r\n\r\n\tbuttonArray.do({arg item, count;\r\n\t\titem.states = [[(count+1).asString, Color.black], [(count+1).asString, Color.black, Color.green]]});\r\n\r\n\tbuttonArray.do({arg item, count;\r\n\t\titem.action = {arg state;\r\n\t\t\tcase\r\n\t\t\t{state.value==1} {notesArray[count] = Synth(\"addsynth\", [\r\n\t\t\t\t\\freq,  fundamental * (count+1),\r\n\t\t\t\t\\amp, 0.1,\r\n\t\t\t\t\\att,  att,\r\n\t\t\t\t\\dec,  dec,\r\n\t\t\t\t\\sus,  sus,\r\n\t\t\t\t\\rel,  rel])}\r\n\t\t\t{state.value==0} {notesArray[count].release}\r\n\t}});\r\n\r\n\tattackSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: 360 @ 30,\r\n\t\tlabel: \"Attack\",\r\n\t\tcontrolSpec: ControlSpec(0.01, 4.0, \\exp, 0.01, 0.1, \"sec\"),\r\n\t\taction: {|ez|  att = ez.value},\r\n\t\tinitVal: 0.01,\r\n\t\tunitWidth: 30)\r\n\t.setColors(\r\n\t\tstringColor: Color.black,\r\n\t\tsliderBackground: Color.grey(0.7),\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\tdecaySlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: 360 @ 30,\r\n\t\tlabel: \"Decay\",\r\n\t\tcontrolSpec: ControlSpec(0.01, 1, \\exp, 0.01, 0.1, \"sec\"),\r\n\t\taction: {|ez|  dec = ez.value},\r\n\t\tinitVal: 0.3,\r\n\t\tunitWidth: 30)\r\n\t.setColors(\r\n\t\tstringColor: Color.black,\r\n\t\tsliderBackground: Color.grey(0.7),\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\tsustainSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: 360 @ 30,\r\n\t\tlabel: \"Sustain\",\r\n\t\tcontrolSpec: ControlSpec(1, 100, \\lin, 1, 75, \"%\"),\r\n\t\taction: {|ez|  sus = ez.value/100.0},\r\n\t\tinitVal: 75,\r\n\t\tunitWidth: 30)\r\n\t.setColors(\r\n\t\tstringColor: Color.black,\r\n\t\tsliderBackground: Color.grey(0.7),\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\treleaseSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: 360 @ 30,\r\n\t\tlabel: \"Release\",\r\n\t\tcontrolSpec: ControlSpec(0.3, 5, \\exp, 0.1, 0.5, \"sec\"),\r\n\t\taction: {|ez|  rel = ez.value},\r\n\t\tinitVal: 0.5,\r\n\t\tunitWidth: 30)\r\n\t.setColors(\r\n\t\tstringColor: Color.black,\r\n\t\tsliderBackground: Color.grey(0.7),\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\tvolumeSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: 360 @ 30,\r\n\t\tlabel: \"VOLUME\",\r\n\t\tcontrolSpec: ControlSpec(1, 100, \\lin, 1, 10, \"%\"),\r\n\t\taction: {|ez|  masterOut.set(\\amp, ez.value/100)},\r\n\t\tinitVal: 10,\r\n\t\tunitWidth: 30)\r\n\t.setColors(\r\n\t\tstringColor: Color.white,\r\n\t\tsliderBackground: Color.grey(0.9),\r\n\t\tnumNormalColor: Color.grey);\r\n\r\n\t// SynthDefs\r\n\r\n\t{\r\n\t\tSynthDef(\"addsynth\", {\r\n\t\t\targ freq = 440, amp = 0.1, gate = 1, att = 0.01, dec = 0.3, sus = 0.5, rel = 1;\r\n\t\t\tvar snd, env;\r\n\t\t\tenv = EnvGen.ar(Env.adsr(att, dec, sus, rel), gate, doneAction: 2);\r\n\t\t\tsnd = SinOsc.ar(freq, 0, amp) * env;\r\n\t\t\tOut.ar(0, snd!2);\r\n\t\t}).add;\r\n\r\n\t\tSynthDef(\\amp, {arg inbus=0, amp = 0.1;\r\n\t\t\tReplaceOut.ar(inbus, In.ar(inbus, 2) * amp);\r\n\t\t}).add;\r\n\r\n\t\t// Wait for SynthDefs to be added...\r\n\t\ts.sync;\r\n\r\n\t\t// Now call the Master Out Synth:\r\n\t\t masterOut = Synth(\"amp\", addAction: \\addToTail);\r\n\r\n\t}.fork;\r\n\r\n\t\"Additive Synthesis Demo 1\".postln;\r\n\t\"\".postln;\r\n\r\n\ts.meter;\r\n\r\n}); // end of block",
   "labels" : [
      "additive synthesis",
      "synthesis techniques"
   ],
   "ancestor_list" : [],
   "description" : "Simple button grid to play first 16 partials of a harmonic series. Horizontal Sliders control ADSR envelope. All partials have equal amplitude.",
   "name" : "Additive Synthesis GUI Demo 1",
   "author" : "Bruno Ruviaro"
}
