{
   "labels" : [
      "fm",
      "synthesis techniques",
      "frequency modulation",
      "frequency ratio"
   ],
   "is_private" : null,
   "id" : "1-4UD",
   "code" : "// ************************************\r\n// Frequency Modulation Fun (GUI)\r\n// Patch 4 - Using Frequency Ratio\r\n// Bruno Ruviaro, 2013-08-12\r\n// ************************************\r\n\r\n/*\r\n\r\nExperiment with frequency modulation by specifying\r\ncontours for Carrier Frequency, Modulation Index,\r\nand Amplitude Envelope. Also adjust duration of events.\r\nIn this version you don't specify Modulator Frequency\r\ndirectly, but rather you specify the Frequency Ratio:\r\n\r\n// freqRatio = carrFreq / modFreq\r\n\r\nFor example, for carrFreq = 440 Hz and // freqRatio = 2,\r\nthen modFreq will be set to 220 Hz. Integer freqRatio\r\nvalues will give you harmonic spectra; Non-integer\r\n\r\nSelect all (ctrl + A), then evaluate (ctrl + period).\r\n\r\n*/\r\n\r\ns.waitForBoot({\r\n\r\n\r\n\t// Envs\r\n\tvar ampEnv, carrFreqEnv, modIndexEnv;\r\n\t// EnvelopeViews\r\n\tvar evCarrFreq, evModIndex, evAmp;\r\n\t// Sliders\r\n\tvar volumeSlider, durationSlider, freqRatioSliderA, freqRatioSliderB, carrFreqSlider, modIndexSlider;\r\n\t// StaticTexts for Frequency Ratio\r\n\tvar freqRatioDisplay, freqRatioDisplaySimplified;\r\n\t// Frequency Ratio variables\r\n\tvar freqRatioA, freqRatioB, freqRatio;\r\n\t// Custom functions\r\n\tvar scaleEnv, updateDisplay, findSimplestRatio, adjustEnv, printEnvData;\r\n\t// Miscellaneous variables\r\n\tvar numberOfPoints, timeScale, win, subwin, font, labelColor, windowColor, presetArray, presetButtons, masterOut;\r\n\r\n\t/*\r\n\t, , , , , , , , , , freqRatioDisplayAnumber, freqRatioDisplayBnumber, , , , , ;\r\n\t*/\r\n\r\n\t///////////////////////////\r\n\t// Various initializations\r\n\t///////////////////////////\r\n\r\n\ttimeScale = 3; // total duration of a \"note\"\r\n\tnumberOfPoints = 8; // how many points in the breakpoint envelopes\r\n\tpresetArray = Array.newClear(12); // number of presets\r\n\tfreqRatioA = 2; // first number for big display A:B\r\n\tfreqRatioB = 1; // second number for big display A:B\r\n\tfreqRatio = freqRatioA / freqRatioB; // for actual Synth call\r\n\tfont = Font(\"Verdana\", 16, bold: true);\r\n\tlabelColor = Color.white;\r\n\twindowColor = Color.grey(0.3);\r\n\r\n\t/////////////////////////\r\n\t// Initialize Envelopes\r\n\t/////////////////////////\r\n\r\n\tcarrFreqEnv = Env.new(\r\n\t\tlevels: {1.0.rand}!numberOfPoints,\r\n\t\ttimes: ({1.0.rand}!(numberOfPoints-1)).normalizeSum\r\n\t);\r\n\r\n\tmodIndexEnv = Env.new(\r\n\t\tlevels: {1.0.rand}!numberOfPoints,\r\n\t\ttimes: ({1.0.rand}!(numberOfPoints-1)).normalizeSum\r\n\t);\r\n\r\n\tampEnv = Env.new(\r\n\t\t// using 'put' to make sure first and last are 0.0\r\n\t\tlevels: ({1.0.rand}!numberOfPoints).put(0, 0).put(numberOfPoints-1, 0),\r\n\t\ttimes: ({1.0.rand}!(numberOfPoints-1)).normalizeSum\r\n\t);\r\n\r\n\t//////////////////////\r\n\t// Initialize Windows\r\n\t//////////////////////\r\n\r\n\tWindow.closeAll;\r\n\r\n\twin = Window.new(\"Frequency Modulation Fun with Frequency Ratio\", Rect(50, 50, 915, 400), resizable: false);\r\n\twin.front;\r\n\twin.background = windowColor;\r\n\twin.alpha = 0.95;\r\n\r\n\t// What to do on close (or ctrl+period)\r\n\twin.onClose = {s.freeAll};\r\n\tCmdPeriod.doOnce({Window.closeAll});\r\n\r\n\tsubwin = FlowView.new(\r\n\t\tparent: win,\r\n\t\tbounds: Rect(710, 230, 185, 150),\r\n\t\tmargin: 10@10,\r\n\t\tgap: 10@10;\r\n\t);\r\n\r\n\t///////////////////////////////\r\n\t// EnvelopeViews (3)\r\n\t///////////////////////////////\r\n\r\n\tevCarrFreq = EnvelopeView(win, Rect(40, 20, 300, 150))\r\n\t// .thumbWidth_(30.0)\r\n\t// .thumbHeight_(15.0)\r\n\t.setEnv(carrFreqEnv)\r\n\t.drawLines_(true)\r\n\t.selectionColor_(Color.red)\r\n\t.drawRects_(true)\r\n\t.step_(0.01)\r\n\t.keepHorizontalOrder_(true)\r\n\t.action_({arg b;\r\n\t\t// [\"GOT IT\", b.value].postln;\r\n\t\t// evCarrFreq.setString(0, 100.rand.asString);\r\n\t\tcarrFreqEnv.levels = b.value[1];\r\n\t\tcarrFreqEnv.times = b.value[0].differentiate.drop(1);\r\n\t\tscaleEnv.value(carrFreqEnv, 50, 1000);\r\n\t})\r\n\t.thumbSize_(18);\r\n\r\n\tevModIndex = EnvelopeView(win, Rect(40, 210, 300, 150))\r\n\t.setEnv(modIndexEnv)\r\n\t.drawLines_(true)\r\n\t.selectionColor_(Color.red)\r\n\t.drawRects_(true)\r\n\t.step_(0.01)\r\n\t.keepHorizontalOrder_(true)\r\n\t.action_({arg b;\r\n\t\tmodIndexEnv.levels = b.value[1];\r\n\t\tmodIndexEnv.times = b.value[0].differentiate.drop(1);\r\n\t\tscaleEnv.value(modIndexEnv, 0, 10);\r\n\t})\r\n\t.thumbSize_(18);\r\n\r\n\tevAmp = EnvelopeView(win, Rect(360, 210, 320, 150))\r\n\t.setEnv(ampEnv)\r\n\t.drawLines_(true)\r\n\t.selectionColor_(Color.red)\r\n\t.drawRects_(true)\r\n\t.step_(0.01)\r\n\t.keepHorizontalOrder_(true)\r\n\t.action_({arg b;\r\n\t\tampEnv.levels = b.value[1];\r\n\t\tampEnv.times = b.value[0].differentiate.drop(1);\r\n\t\tampEnv.duration_(timeScale);\r\n\t})\r\n\t.thumbSize_(18);\r\n\r\n\t///////////////////////////////\r\n\t// Sliders (6)\r\n\t///////////////////////////////\r\n\r\n\t// carrFreq\r\n\tcarrFreqSlider = Slider(win, Rect(20, 21, 20, 148))\r\n\t.action_({arg slider;\r\n\t\tvar v = slider.value;\r\n\t\tcarrFreqEnv = Env.new(\r\n\t\t\tlevels: v!numberOfPoints, // straight line\r\n\t\t\ttimes: (0.1!(numberOfPoints-1)).normalizeSum);\r\n\t\tevCarrFreq.setEnv(carrFreqEnv);\r\n\t\tevCarrFreq.action.value(evCarrFreq); // does all the stuff\r\n\t});\r\n\r\n\t// modIndex\r\n\tmodIndexSlider = Slider(win, Rect(20, 210, 20, 148))\r\n\t.action_({arg slider;\r\n\t\tvar v = slider.value;\r\n\t\tmodIndexEnv = Env.new(\r\n\t\t\tlevels: v!numberOfPoints, // straight line\r\n\t\t\ttimes: (0.1!(numberOfPoints-1)).normalizeSum);\r\n\t\tevModIndex.setEnv(modIndexEnv);\r\n\t\tevModIndex.action.value(evModIndex); // does all the stuff\r\n\t});\r\n\r\n\t// freqRatio A\r\n\tfreqRatioSliderA = Slider(win, Rect(360, 21, 40, 148))\r\n\t.action_({arg slider;\r\n\t\tvar a = (slider.value*8+1).round(1).asInteger; // integers only\r\n\t\tfreqRatioA = a;\r\n\t\tfreqRatio = freqRatioA / freqRatioB;\r\n\t\tupdateDisplay.value;\r\n\t});\r\n\r\n\t// freqRatio B\r\n\tfreqRatioSliderB = Slider(win, Rect(640, 21, 40, 148))\r\n\t.action_({arg slider;\r\n\t\tvar b = (slider.value*9+0.1).round(0.1); // may have decimals\r\n\t\tfreqRatioB = b;\r\n\t\tfreqRatio = freqRatioA / freqRatioB;\r\n\t\tupdateDisplay.value;\r\n\t});\r\n\r\n\t// master volume\r\n\tvolumeSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: Rect(830, 10, 50, 170),\r\n\t\tlabel: \"volume\",\r\n\t\tcontrolSpec: ControlSpec(-60, 0, \\lin, 1, -40, \"dB\"),\r\n\t\taction: {|ez| masterOut.set(\\amp, ez.value.dbamp)},\r\n\t\tunitWidth: 30,\r\n\t\tlabelWidth: 80,\r\n\t\tlayout: 'vert')\r\n\t.setColors(\r\n\t\tstringColor: labelColor,\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\tvolumeSlider.numberView.align = \\center;\r\n\tvolumeSlider.unitView.align = \\center;\r\n\r\n\t// duration\r\n\tdurationSlider = EZSlider(\r\n\t\tparent: win,\r\n\t\tbounds: Rect(665, 184, 240, 40),\r\n\t\tlabel: \"dur\",\r\n\t\tcontrolSpec: ControlSpec(1, 13, \\lin, 0.1, timeScale, \"sec\"),\r\n\t\taction: {|ez|\r\n\t\t\ttimeScale = ez.value;\r\n\t\t\tevCarrFreq.action.value(evCarrFreq);\r\n\t\t\tevModIndex.action.value(evModIndex);\r\n\t\t\tevAmp.action.value(evAmp)},\r\n\t\tnumberWidth: 35,\r\n\t\tunitWidth: 30,\r\n\t\tlayout: 'horz')\r\n\t.setColors(\r\n\t\tstringColor: labelColor,\r\n\t\tnumNormalColor: Color.black);\r\n\r\n\tdurationSlider.numberView.align = \\center;\r\n\r\n\r\n\t///////////////////////////////\r\n\t// Static Texts (4)\r\n\t///////////////////////////////\r\n\r\n\t// freqRatio Big Display\r\n\tfreqRatioDisplay = StaticText(win, Rect(400, 20, 240, 140))\r\n\t// .background_(Color.blue)\r\n\t.string_(freqRatioA.asString ++ \":\" ++ freqRatioB.asString)\r\n\t.font_(Font(\"Verdana\", 80))\r\n\t.align_(\\center)\r\n\t.stringColor = Color.grey;\r\n\r\n\t// freqRatio Small Display (simplest ratio equivalence)\r\n\tfreqRatioDisplaySimplified = StaticText(win, Rect(400, 140, 240, 20))\r\n\t// .background_(Color.blue)\r\n\t.string_(\" \") // display empty at initialization\r\n\t.font_(Font(\"Verdana\", 18))\r\n\t.align_(\\center)\r\n\t.stringColor = Color.grey;\r\n\r\n\t// Unnamed StaticTexts (labels)\r\n\tStaticText(win, Rect(20, 165, 200, 40))\r\n\t.string_(\"Carrier Frequency\")\r\n\t.font_(font)\r\n\t.stringColor = labelColor;\r\n\tStaticText(win, Rect(445, 160, 250, 40))\r\n\t.string_(\"Frequency Ratio\")\r\n\t.font_(font)\r\n\t.stringColor = labelColor;\r\n\tStaticText(win, Rect(20, 355, 250, 40))\r\n\t.string_(\"Modulation Index\")\r\n\t.font_(font)\r\n\t.stringColor = labelColor;\r\n\tStaticText(win, Rect(360, 355, 250, 40))\r\n\t.string_(\"Amplitude Envelope\")\r\n\t.font_(font)\r\n\t.stringColor = labelColor;\r\n\r\n\t///////////////////////////////\r\n\t// Buttons (14)\r\n\t///////////////////////////////\r\n\r\n\t// Play\r\n\tButton(win, Rect(710, 21, 100, 147))\r\n\t.states_([[\"PLAY\", Color.black]])\r\n\t.action_({\r\n\t\t// All Envs arrive here already scaled (levels and times)!\r\n\t\t// Custom function \"scaleEnv\" is used elsewhere every time\r\n\t\t// a change is made (EnvViews or Sliders).\r\n\t\tSynth.new(\"freq-mod-with-envs\", [\r\n\t\t\t\\carrFreqEnv, carrFreqEnv,\r\n\t\t\t\\freqRatio, freqRatio,\r\n\t\t\t\\modIndexEnv, modIndexEnv,\r\n\t\t\t\\ampEnv, ampEnv\r\n\t\t]);\r\n\t})\r\n\t.font_(Font(\"Verdana\", 20));\r\n\r\n\t// 12 Presets\r\n\tpresetButtons = Array.fill(12, {arg i;\r\n\t\tButton(subwin, 30@30)\r\n\t\t.states_([[i.asString]])\r\n\t\t.action_({presetArray[i].value; \"Preset % recalled\".postf(i); \"\".postln});\r\n\t});\r\n\r\n\t// Print current settings\r\n\tButton(subwin, 150@20)\r\n\t.states_([[\"print current settings\"]])\r\n\t.action_({\r\n\t\t\"**************************\".postln;\r\n\t\t\"**************************\".postln;\r\n\t\t\"To save the settings below as a Preset,\".postln;\r\n\t\t\"copy all lines and paste them into\".postln;\r\n\t\t\"one of the existing preset functions\".postln;\r\n\t\t\"For instance,\".postln;\r\n\t\t\"\".postln;\r\n\t\t\"presetArray[9] = { <copy settings here> };\".postln;\r\n\t\t\"\".postln;\r\n\t\t\"**************************\".postln;\r\n\t\tprintEnvData.value;\r\n\t\t\"**************************\".postln;\r\n\t});\r\n\r\n\r\n\t//////////////////////////////////////////\r\n\t// Custom functions\r\n\t//////////////////////////////////////////\r\n\r\n\t// This simple custom function just scales an Envelope\r\n\t// to desired ranges (levels, times) so that it is\r\n\t// ready to go when a Synth uses them.\r\n\tscaleEnv = {arg thisEnv, minVal, maxVal;\r\n\r\n\t\tthisEnv.levels = thisEnv.levels.linlin(0, 1, minVal, maxVal);\r\n\t\tthisEnv.duration_(timeScale);\r\n\t\tthisEnv.duration_(timeScale);\r\n\t\t// \"scaling done!\".postln;\r\n\t};\r\n\r\n\t// Ugly...\r\n\tadjustEnv = {arg anEnv, inMin = 50, inMax = 1000;\r\n\t\tvar anotherEnv = Env.newClear(numberOfPoints);\r\n\t\tanotherEnv.levels = anEnv.levels.linlin(inMin, inMax, 0, 1);\r\n\t\tanotherEnv.times = anEnv.times;\r\n\t};\r\n\r\n\t// Find simplest ratio (for display purposes only).\r\n\t// Returns a String to be used directly in freqRatioDisplaySimplified\r\n\tfindSimplestRatio = {arg a, b;\r\n\r\n\t\tvar test = b.round(0.1).frac;\r\n\t\tvar results;\r\n\r\n\t\tcase\r\n\r\n\t\t// b is integer\r\n\t\t{test==0.0} {\r\n\t\t\tvar gcd = gcd(a.asInteger, b.asInteger);\r\n\t\t\t// if already at simplest possible integer ratio,\r\n\t\t\t// display nothing;\r\n\t\t\t// else, display simplest integer ratio\r\n\t\t\tif(gcd==1,\r\n\t\t\t\t{\" \"},\r\n\t\t\t\t{\r\n\t\t\t\t\tresults = [a, b] / gcd;\r\n\t\t\t\t\tresults[0].asString ++ \":\" ++ results[1].asString\r\n\t\t\t\t}\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t// b is x.5\r\n\t\t{test==0.5} {\r\n\t\t\ta = a * 2;\r\n\t\t\tb = b * 2;\r\n\t\t\t// from above, e.g., 2:1.5 (a:b) becomes 4:3, etc.\r\n\t\t\tresults = [a, b] / gcd(a.asInteger, b.asInteger);\r\n\t\t\tresults[0].asString ++ \":\" ++ results[1].asString;\r\n\t\t}\r\n\r\n\t\t// b is non-Integer and non x.5, no simplest ratio available\r\n\t\t{true} {\" \"};\r\n\t};\r\n\r\n\tupdateDisplay = {\r\n\r\n\t\tfreqRatioDisplay.string = freqRatioA.asString ++ \":\" ++ freqRatioB.asString;\r\n\t\tfreqRatioDisplaySimplified.string = findSimplestRatio.value(freqRatioA, freqRatioB);\r\n\r\n\t};\r\n\r\n\t//\r\n\t// Initialize very first envelope views (at time of first eval)\r\n\t//\r\n\r\n\tevCarrFreq.action.value(evCarrFreq);\r\n\tevModIndex.action.value(evModIndex);\r\n\tevAmp.action.value(evAmp);\r\n\r\n\r\n\t////////////////\r\n\t// SynthDefs\r\n\t////////////////\r\n\r\n\t{\r\n\r\n\t\tSynthDef(\"freq-mod-with-envs\", {arg freqRatio;\r\n\r\n\t\t\tvar carrFreq, carrFreqEnv, carrFreqCtl, modFreq, modFreqEnv, modFreqCtl, modIndex, modIndexEnv, modIndexCtl, carrier, modulator, amp, ampEnv, ampCtl;\r\n\r\n\t\t\t// Note: variable 'numberOfPoints' is\r\n\t\t\t// defined at very beginning of the page.\r\n\r\n\t\t\tcarrFreqEnv = Env.newClear(numberOfPoints);\r\n\t\t\tcarrFreqCtl = \\carrFreqEnv.kr(carrFreqEnv.asArray);\r\n\t\t\tcarrFreq = EnvGen.kr(carrFreqCtl);\r\n\r\n\t\t\t// A:B = carrFreq:modFreq, thus carrFreq = modFreq * B/A\r\n\t\t\tmodFreq = carrFreq * freqRatio.reciprocal;\r\n\r\n\t\t\tmodIndexEnv = Env.newClear(numberOfPoints);\r\n\t\t\tmodIndexCtl = \\modIndexEnv.kr(modIndexEnv.asArray);\r\n\t\t\tmodIndex = EnvGen.kr(modIndexCtl);\r\n\r\n\t\t\tampEnv = Env.newClear(numberOfPoints);\r\n\t\t\tampCtl = \\ampEnv.kr(ampEnv.asArray);\r\n\t\t\tamp = EnvGen.kr(ampCtl, doneAction: 2);\r\n\r\n\t\t\tmodulator = SinOsc.ar(freq: modFreq, mul: modIndex * modFreq);\r\n\t\t\tcarrier = SinOsc.ar(freq: carrFreq + modulator, mul: amp);\r\n\r\n\t\t\tOut.ar(0, [carrier, carrier]);\r\n\r\n\t\t}).add;\r\n\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\tmasterOut = Synth(\"amp\", [\\amp, volumeSlider.value.dbamp], addAction: \\addToTail);\r\n\r\n\t}.fork;\r\n\r\n\r\n\t///////////////////////////\r\n\t//////// 12 PRESETS ///////\r\n\t///////////////////////////\r\n\r\n\tpresetArray[0] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 715, 715, 715, 715, 715, 715, 715, 715 ],[ 0.294, 0.315, 0.294, 0.294, 0.294, 0.315, 0.294 ]);\r\n\t\tmodIndexEnv = Env.new([ 3.7, 3.5, 3.2, 3.1, 2.8, 2.4, 2, 0 ],[ 0.21, 0.252, 0.252, 0.294, 0.231, 0.546, 0.315 ]);\r\n\t\tampEnv = Env.new([ 0, 0.02, 0.08, 0.2, 0.31, 0.57, 0.97, 0 ],[ 0.588, 0.441, 0.462, 0.294, 0.105, 0.147, 0.063 ]);\r\n\t\tfreqRatio = 2/3;\r\n\t\tfreqRatioSliderA.valueAction = 0.15873015873016;\r\n\t\tfreqRatioSliderB.valueAction = 0.32539682539683;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 2.1;\r\n\t\tdurationSlider.value = 2.1;\r\n\r\n\t};\r\n\r\n\tpresetArray[1] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 905, 905, 905, 905, 905, 905, 905, 905 ],[ 0.294, 0.315, 0.294, 0.294, 0.294, 0.315, 0.294 ]);\r\n\t\tmodIndexEnv = Env.new([ 3.7, 3.5, 3.2, 3.1, 2.8, 2.4, 2, 0 ],[ 0.21, 0.252, 0.252, 0.294, 0.231, 0.546, 0.315 ]);\r\n\t\tampEnv = Env.new([ 0, 1, 0.58, 0.31, 0.18, 0.09, 0.05, 0 ],[ 0.042, 0.084, 0.231, 0.315, 0.462, 0.504, 0.462 ]);\r\n\t\tfreqRatio = 2/6.4;\r\n\t\tfreqRatioSliderA.valueAction = 0.15873015873016;\r\n\t\tfreqRatioSliderB.valueAction = 0.6984126984127;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 2.1;\r\n\t\tdurationSlider.value = 2.1;\r\n\r\n\r\n\t};\r\n\r\n\tpresetArray[2] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 145, 145, 145, 145, 145, 145, 145, 145 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tmodIndexEnv = Env.new([ 3.7, 3.7, 3.7, 3.7, 3.7, 3.7, 3.7, 3.7 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tampEnv = Env.new([ 0, 1, 0.76, 0.47, 0.29, 0.2, 0.09, 0 ],[ 0, 0.112, 0.24, 0.352, 0.304, 0.256, 0.336 ]);\r\n\t\tfreqRatio = 2/5;\r\n\t\tfreqRatioSliderA.valueAction = 0.16666666666667;\r\n\t\tfreqRatioSliderB.valueAction = 0.54761904761905;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1.6;\r\n\t\tdurationSlider.value = 1.6;\r\n\r\n\t};\r\n\r\n\tpresetArray[3] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 145, 145, 145, 145, 145, 145, 145, 145 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tmodIndexEnv = Env.new([ 3.7, 3.7, 3.7, 3.7, 3.7, 3.7, 3.7, 3.7 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tampEnv = Env.new([ 0, 1, 0.76, 0.47, 0.29, 0.2, 0.09, 0 ],[ 0, 0.112, 0.24, 0.352, 0.304, 0.256, 0.336 ]);\r\n\t\tfreqRatio = 1/1;\r\n\t\tfreqRatioSliderA.valueAction = 0.047619047619048;\r\n\t\tfreqRatioSliderB.valueAction = 0.1031746031746;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1.6;\r\n\t\tdurationSlider.value = 1.6;\r\n\r\n\t};\r\n\r\n\tpresetArray[4] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tmodIndexEnv = Env.new([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tampEnv = Env.new([ 0, 0.98, 1, 0.67, 0.38, 0.18, 0.08, 0 ],[ 0, 0.16, 0.24, 0.4, 0.208, 0.224, 0.368 ]);\r\n\t\tfreqRatio = 3/2;\r\n\t\tfreqRatioSliderA.valueAction = 0.3015873015873;\r\n\t\tfreqRatioSliderB.valueAction = 0.20634920634921;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1.6;\r\n\t\tdurationSlider.value = 1.6;\r\n\r\n\r\n\t};\r\n\r\n\tpresetArray[5] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tmodIndexEnv = Env.new([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tampEnv = Env.new([ 0, 0.98, 1, 0.67, 0.38, 0.18, 0.08, 0 ],[ 0, 0.16, 0.24, 0.4, 0.208, 0.224, 0.368 ]);\r\n\t\tfreqRatio = 1/2;\r\n\t\tfreqRatioSliderA.valueAction = 0.0079365079365079;\r\n\t\tfreqRatioSliderB.valueAction = 0.20634920634921;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1.6;\r\n\t\tdurationSlider.value = 1.6;\r\n\r\n\t};\r\n\r\n\tpresetArray[6] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5, 724.5 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tmodIndexEnv = Env.new([ 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6 ],[ 0.224, 0.24, 0.224, 0.224, 0.224, 0.24, 0.224 ]);\r\n\t\tampEnv = Env.new([ 0, 0.98, 1, 0.67, 0.38, 0.18, 0.08, 0 ],[ 0, 0.16, 0.24, 0.4, 0.208, 0.224, 0.368 ]);\r\n\t\tfreqRatio = 1/3;\r\n\t\tfreqRatioSliderA.valueAction = 0.0079365079365079;\r\n\t\tfreqRatioSliderB.valueAction = 0.32539682539683;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1.6;\r\n\t\tdurationSlider.value = 1.6;\r\n\r\n\t};\r\n\r\n\tpresetArray[7] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000 ],[ 0.308, 0.33, 0.308, 0.308, 0.308, 0.33, 0.308 ]);\r\n\t\tmodIndexEnv = Env.new([ 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6, 3.6 ],[ 0.308, 0.33, 0.308, 0.308, 0.308, 0.33, 0.308 ]);\r\n\t\tampEnv = Env.new([ 0, 1, 1, 0.76, 0.38, 0.18, 0.08, 0 ],[ 0, 0.22, 0.528, 0.352, 0.286, 0.308, 0.506 ]);\r\n\t\tfreqRatio = 2/1.2;\r\n\t\tfreqRatioSliderA.valueAction = 0.12698412698413;\r\n\t\tfreqRatioSliderB.valueAction = 0.11904761904762;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 2.2;\r\n\t\tdurationSlider.value = 2.2;\r\n\r\n\t};\r\n\r\n\tpresetArray[8] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 411, 392, 335, 354, 335, 392, 373, 449 ],[ 0.60618556701031, 0.51958762886598, 0.64948453608247, 0.64948453608247, 0.64948453608247, 0.56288659793814, 0.56288659793814 ]);\r\n\t\tmodIndexEnv = Env.new([ 0, 0.8, 2.1, 2.3, 3.4, 6, 5.9, 0 ],[ 0.59393939393939, 0.76363636363636, 1.0606060606061, 0.50909090909091, 0.38181818181818, 0.63636363636364, 0.25454545454545 ]);\r\n\t\tampEnv = Env.new([ 0, 0.71, 0.74, 0.74, 0.84, 0.75, 0.35, 0 ],[ 0.756, 0.714, 0.63, 0.294, 0.42, 0.378, 1.008 ]);\r\n\t\tfreqRatio = 7/3;\r\n\t\tfreqRatioSliderA.valueAction = 0.76984126984127;\r\n\t\tfreqRatioSliderB.valueAction = 0.32539682539683;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 4.2;\r\n\t\tdurationSlider.value = 4.2;\r\n\r\n\r\n\t};\r\n\r\n\tpresetArray[9] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 648.5, 601, 667.5, 620, 667.5, 629.5, 648.5, 648.5 ],[ 0.08, 0.06, 0.06, 0.07, 0.08, 0.51, 0.14 ]);\r\n\t\tmodIndexEnv = Env.new([ 10, 10, 10, 9.7, 10, 10, 3.8, 0 ],[ 0.13, 0.09, 0.12, 0.16, 0.19, 0.09, 0.22 ]);\r\n\t\tampEnv = Env.new([ 0, 0.73, 0.7, 0.57, 0.48, 0.21, 0.8, 0 ],[ 0.03, 0.21, 0.18, 0.18, 0.05, 0.22, 0.13 ]);\r\n\t\tfreqRatio = 8/3;\r\n\t\tfreqRatioSliderA.valueAction = 0.83333333333333;\r\n\t\tfreqRatioSliderB.valueAction = 0.32539682539683;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1;\r\n\t\tdurationSlider.value = 1;\r\n\r\n\t};\r\n\r\n\tpresetArray[10] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 800.5, 800.5, 800.5, 800.5, 800.5, 800.5, 800.5, 800.5 ],[ 0.14, 0.15, 0.14, 0.14, 0.14, 0.15, 0.14 ]);\r\n\t\tmodIndexEnv = Env.new([ 5.1, 4.9, 3.9, 3.6, 3.7, 2.6, 1.2, 1.2 ],[ 0.05, 0.08, 0.09, 0.07, 0.21, 0.33, 0.17 ]);\r\n\t\tampEnv = Env.new([ 0, 0.82, 0.7, 0.57, 0.48, 0.41, 0.32, 0 ],[ 0.02, 0.22, 0.18, 0.18, 0.12, 0.14, 0.14 ]);\r\n\t\tfreqRatio = 3/2;\r\n\t\tfreqRatioSliderA.valueAction = 0.23809523809524;\r\n\t\tfreqRatioSliderB.valueAction = 0.20634920634921;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 1;\r\n\t\tdurationSlider.value = 1;\r\n\r\n\t};\r\n\r\n\tpresetArray[11] = {\r\n\r\n\t\tcarrFreqEnv = Env.new([ 506, 211.5, 287.5, 990.5, 990.5, 933.5, 192.5, 50 ],[ 0.69, 0.48, 0.3, 0.18, 0.27, 0.63, 0.45 ]);\r\n\t\tmodIndexEnv = Env.new([ 6.6, 1.9, 7.4, 2.9, 0.5, 2.4, 1.2, 1.2 ],[ 0.66, 0.18, 0.54, 0.09, 0.54, 0.48, 0.51 ]);\r\n\t\tampEnv = Env.new([ 0, 0.94, 0.93, 1, 1, 0.84, 0.71, 0 ],[ 0.27, 0.54, 0.66, 0.84, 0.24, 0.27, 0.18 ]);\r\n\t\tfreqRatio = 6/1;\r\n\t\tfreqRatioSliderA.valueAction = 0.57142857142857;\r\n\t\tfreqRatioSliderB.valueAction = 0.095238095238095;\r\n\t\tevCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\r\n\t\tevModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\r\n\t\tevAmp.setEnv(ampEnv);\r\n\t\ttimeScale = 3;\r\n\t\tdurationSlider.value = 3;\r\n\r\n\t};\r\n\r\n\t/////////////////////////////////////////////\r\n\t// Function: \"Print Current Settings\" ///////\r\n\t/////////////////////////////////////////////\r\n\r\n\tprintEnvData = {\r\n\r\n\t\t(\"carrFreqEnv = Env.new(\" ++ carrFreqEnv.levels ++ \",\" ++ carrFreqEnv.times ++ \");\").postln;\r\n\r\n\t\t(\"modIndexEnv = Env.new(\" ++ modIndexEnv.levels ++ \",\" ++ modIndexEnv.times ++ \");\").postln;\r\n\r\n\t\t(\"ampEnv = Env.new(\" ++ ampEnv.levels ++ \",\" ++ ampEnv.times ++ \");\").postln;\r\n\r\n\t\t(\"freqRatio = \" ++ freqRatioA ++ \"/\" ++ freqRatioB ++ \";\").postln;\r\n\r\n\t\t(\"freqRatioSliderA.valueAction = \" ++ freqRatioSliderA.value ++ \";\").postln;\r\n\r\n\t\t(\"freqRatioSliderB.valueAction = \" ++ freqRatioSliderB.value ++ \";\").postln;\r\n\r\n\t\t\"evCarrFreq.setEnv(adjustEnv.value(carrFreqEnv));\".postln;\r\n\r\n\t\t\"evModIndex.setEnv(adjustEnv.value(modIndexEnv, 0, 10));\".postln;\r\n\r\n\t\t\"evAmp.setEnv(ampEnv);\".postln;\r\n\r\n\t\t(\"timeScale = \" ++ timeScale ++ \";\").postln;\r\n\r\n\t\t(\"durationSlider.value = \" ++ timeScale ++ \";\").postln;\r\n\r\n\t};\r\n\r\n\r\n}); // end of block",
   "author" : "Bruno Ruviaro",
   "name" : "Frequency Modulation GUI Demo 4",
   "description" : "Experiment with FM by specifying contours for Carrier Frequency, Modulation Index, and Amplitude Envelope. Also adjust duration of events. In this version you don't specify Modulator Frequency directly, but rather you specify the Frequency Ratio.",
   "ancestor_list" : []
}
