{
   "name" : "waveshaping animation",
   "author" : "eli.fieldsteel",
   "description" : "GUI animation for signal waveshaping",
   "ancestor_list" : [],
   "labels" : [
      "animation",
      "waveshaping"
   ],
   "code" : "(\r\n//after running code, esc key to close window and abort animation\r\n\r\n~mainRoutine = {\r\n\tvar input, transfer, output,\r\n\tinputVertAxis, transferHorizAxis,\r\n\twin, inputView, transferView, outputView,\r\n\tinc=(0), animate=true;\r\n\r\n\t/*----------------------------------*/\r\n\t//user can set \"input\" and \"transfer\"\r\n\t//variables to be any Signal of size 384\r\n\t//\r\n\t//animation will show the output signal\r\n\t//that results from waveshaping\r\n\t/*----------------------------------*/\r\n\r\n\t//sine wave\r\n\tinput = Signal.sineFill(384,[1],[0]);\r\n\r\n\t//uncomment for other input options, or DIY\r\n\t//input = Signal.sineFill(384, reverse(sort({exprand(0.1,1)}!5)), [pi,pi,pi,0,pi/3]);\r\n\t//input = Env({rrand(-0.99,0.99)}!15,({exprand(0.1,1)}!14),({rrand(-10.0,10.0)}!14)).discretize(384);\r\n\t//input = Env([0,1,-1,0],[1,2,1],[0,0,0]).asSignal(384).cubed;\r\n\r\n\t//identity transfer function\r\n\ttransfer = Env([-1,1],[1],[0]).asSignal(384);\r\n\r\n\t//uncomment for other transfer options, or DIY:\r\n\t//transfer = Env([-0.5,0.5],[1],[0]).asSignal(384);\r\n\t//transfer = Env([-0.8,0,0.8],[1,1],[8,-8]).asSignal(384);\r\n\t//transfer = Env([-0.5,-0.2,-0.9,0.9,0.2,0.5],[1,1,2,1,1],\\sine).asSignal(384);\r\n\r\n\t//do not edit output variable:\r\n\t//output is calculated from input & transfer above\r\n\toutput = Signal.newClear(384);\r\n\toutput = output.waveFill({\r\n\t\targ x, old, i;\r\n\t\ttransfer.blendAt(input[i].linlin(-1,1,0,384));\r\n\t});\r\n\r\n\tWindow.closeAll;\r\n\twin = Window.new(\"\", Window.screenBounds, false, false).front;\r\n\twin.view.background_(Color.gray(0.1));\r\n\twin.view.keyDownAction_({\r\n\t\targ view, char, mod, uni;\r\n\r\n\t\t//esc to abort & close window\r\n\t\tif(uni == 27, {~animate.stop;~mainRoutine.stop;win.close;})\r\n\t});\r\n\r\n\tStaticText(win, Rect(60,634,384,48))\r\n\t.font_(Font(Font.defaultSansFace, 36))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"input signal\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(400,347,50,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"time\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(218,170,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"+1\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(219,554,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"-1\")\r\n\t.align_(\\center);\r\n\r\n\tinputVertAxis = UserView.new(win, Rect(20,180,26,384)).background_(Color.clear);\r\n\r\n\tinputVertAxis.drawFunc_({\r\n\t\tPen.width_(5);\r\n\t\tPen.strokeColor_(Color.new(0,0.75,1,0.5));\r\n\r\n\t\tPen.addArc(\r\n\t\t\tPoint(\r\n\t\t\t\t13,\r\n\t\t\t\tinput[inc].linlin(-1.02,1.02,384,0)\r\n\t\t\t),\r\n\t\t\t10, 0, 2pi\r\n\t\t);\r\n\t\tPen.stroke;\r\n\r\n\t});\r\n\r\n\tinputView = UserView.new(win, Rect(60,180,384,384)).background_(Color.clear);\r\n\tinputView.clearOnRefresh_(true);\r\n\tinputView.drawFunc = {nil};\r\n\tinputView.refresh;\r\n\tinputView.drawFunc_({\r\n\t\tPen.strokeColor_(Color.gray(0.2));\r\n\t\tPen.width_(2);\r\n\t\tPen.line(192@0, 192@384);\r\n\t\tPen.line(0@192,384@192);\r\n\t\tPen.stroke;\r\n\t\tPen.strokeColor_(Color.gray(0.4));\r\n\t\tPen.width_(5);\r\n\t\tPen.moveTo(0@384);\r\n\r\n\t\t(input.size-1).do{\r\n\t\t\targ i;\r\n\t\t\tPen.line(\r\n\t\t\t\tPoint(i, input[i].linlin(-1.02,1.02,384,0)),\r\n\t\t\t\tPoint(i+1, input[i+1].linlin(-1.02,1.02,384,0))\r\n\t\t\t);\r\n\t\t\tPen.stroke;\r\n\t\t};\r\n\r\n\t});\r\n\r\n\tStaticText(win, Rect(517,634,384,48))\r\n\t.font_(Font(Font.defaultSansFace, 36))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"transfer function\")\r\n\t.align_(\\center);\r\n\r\n\r\n\tStaticText(win, Rect(870,347,50,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"+1\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(492,347,50,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"-1\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(673,170,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"+1\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(674,554,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"-1\")\r\n\t.align_(\\center);\r\n\r\n\ttransferHorizAxis = UserView.new(win, Rect(517,140,384,26)).background_(Color.clear);\r\n\r\n\ttransferHorizAxis.drawFunc_({\r\n\t\tPen.width_(5);\r\n\t\tPen.strokeColor_(Color.new(0,0.75,1,0.5));\r\n\r\n\t\tPen.addArc(\r\n\t\t\tPoint(\r\n\t\t\t\tinput[inc].linlin(-1.02,1.02,0,384),\r\n\t\t\t\t13\r\n\t\t\t),\r\n\t\t\t10, 0, 2pi\r\n\t\t);\r\n\t\tPen.stroke;\r\n\r\n\t});\r\n\r\n\ttransferView = UserView.new(win, Rect(517,180,384,384)).background_(Color.clear);\r\n\ttransferView.clearOnRefresh_(true);\r\n\ttransferView.drawFunc = {nil};\r\n\ttransferView.refresh;\r\n\ttransferView.drawFunc_({\r\n\t\tPen.strokeColor_(Color.gray(0.2));\r\n\t\tPen.width_(2);\r\n\t\tPen.line(192@0, 192@384);\r\n\t\tPen.line(0@192,384@192);\r\n\t\tPen.stroke;\r\n\t\tPen.strokeColor_(Color.gray(0.4));\r\n\t\tPen.width_(5);\r\n\t\tPen.moveTo(0@384);\r\n\r\n\t\t(transfer.size-1).do{\r\n\t\t\targ i;\r\n\t\t\tPen.line(\r\n\t\t\t\tPoint(i, transfer[i].linlin(-1.02,1.02,384,0)),\r\n\t\t\t\tPoint(i+1, transfer[i+1].linlin(-1.02,1.02,384,0))\r\n\t\t\t);\r\n\t\t\tPen.stroke;\r\n\t\t};\r\n\r\n\t});\r\n\ttransferView.refresh;\r\n\r\n\tStaticText(win, Rect(974,634,384,48))\r\n\t.font_(Font(Font.defaultSansFace, 36))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"output signal\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(1314,347,50,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"time\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(1132,170,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"+1\")\r\n\t.align_(\\center);\r\n\r\n\tStaticText(win, Rect(1133,554,30,20))\r\n\t.font_(Font(Font.defaultSansFace, 18))\r\n\t.stringColor_(Color.gray(0.8))\r\n\t.string_(\"-1\")\r\n\t.align_(\\center);\r\n\r\n\toutputView = UserView.new(win, Rect(974,180,384,384)).background_(Color.clear);\r\n\toutputView.clearOnRefresh_(true);\r\n\toutputView.drawFunc = {nil};\r\n\toutputView.refresh;\r\n\toutputView.drawFunc_({\r\n\t\tPen.strokeColor_(Color.gray(0.2));\r\n\t\tPen.width_(2);\r\n\t\tPen.line(192@0, 192@384);\r\n\t\tPen.line(0@192,384@192);\r\n\t\tPen.stroke;\r\n\t\tPen.strokeColor_(Color.gray(0.4));\r\n\t\tPen.width_(5);\r\n\t\tPen.moveTo(0@384);\r\n\t\t// (input.size-1).do{\r\n\t\t// \targ i;\r\n\t\t// \tPen.line(\r\n\t\t// \t\tPoint(i, input[i].linlin(-1.02,1.02,384,0)),\r\n\t\t// \t\tPoint(i+1, input[i+1].linlin(-1.02,1.02,384,0))\r\n\t\t// \t);\r\n\t\t// \tPen.stroke;\r\n\t\t// };\r\n\t\tPen.stroke;\r\n\t});\r\n\toutputView.refresh;\r\n\r\n\t1.wait;\r\n\r\n\tif(animate, {\r\n\r\n\t\t{\r\n\t\t\tinc = -1;\r\n\r\n\t\t\tinputView.clearOnRefresh_(false);\r\n\t\t\tinputView.drawFunc_({\r\n\t\t\t\tPen.strokeColor_(Color.gray(0.9));\r\n\t\t\t\tPen.width_(5);\r\n\t\t\t\tPen.line(\r\n\t\t\t\t\tPoint(inc, input[inc].linlin(-1.02,1.02,384,0)),\r\n\t\t\t\t\tPoint(inc+1, input[inc+1].linlin(-1.02,1.02,384,0))\r\n\t\t\t\t);\r\n\t\t\t\tPen.stroke;\r\n\t\t\t});\r\n\r\n\t\t\ttransferView.clearOnRefresh_(true);\r\n\t\t\ttransferView.drawFunc_({\r\n\t\t\t\tPen.strokeColor_(Color.gray(0.2));\r\n\t\t\t\tPen.width_(2);\r\n\t\t\t\tPen.line(192@0, 192@384);\r\n\t\t\t\tPen.line(0@192,384@192);\r\n\t\t\t\tPen.stroke;\r\n\t\t\t\tPen.strokeColor_(Color.gray(0.4));\r\n\t\t\t\tPen.width_(5);\r\n\t\t\t\tPen.moveTo(0@384);\r\n\r\n\t\t\t\t(transfer.size-1).do{\r\n\t\t\t\t\targ i;\r\n\t\t\t\t\tPen.line(\r\n\t\t\t\t\t\tPoint(i, transfer[i].linlin(-1.02,1.02,384,0)),\r\n\t\t\t\t\t\tPoint(i+1, transfer[i+1].linlin(-1.02,1.02,384,0))\r\n\t\t\t\t\t);\r\n\t\t\t\t\tPen.stroke;\r\n\t\t\t\t};\r\n\t\t\t\tPen.strokeColor_(Color.new(0,0.75,1));\r\n\t\t\t\tPen.addArc(\r\n\t\t\t\t\tPoint(\r\n\t\t\t\t\t\tinput[inc].linlin(-1.02,1.02,0,384),\r\n\t\t\t\t\t\ttransfer[input[inc].linlin(-1.02,1.02,0,384)].linlin(-1.02,1.02,384,0)\r\n\t\t\t\t\t),\r\n\t\t\t\t\t10, 0, 2pi\r\n\t\t\t\t);\r\n\t\t\t\tPen.stroke;\r\n\t\t\t});\r\n\r\n\t\t\toutputView.clearOnRefresh_(false);\r\n\t\t\toutputView.drawFunc_({\r\n\t\t\t\tPen.strokeColor_(Color.gray(0.9));\r\n\t\t\t\tPen.width_(5);\r\n\t\t\t\tPen.line(\r\n\t\t\t\t\tPoint(inc, output[inc].linlin(-1.02,1.02,384,0)),\r\n\t\t\t\t\tPoint(inc+1, output[inc+1].linlin(-1.02,1.02,384,0))\r\n\t\t\t\t);\r\n\t\t\t\tPen.stroke;\r\n\t\t\t});\r\n\r\n\t\t\t~animate = {\r\n\t\t\t\twhile(\r\n\t\t\t\t\t{inc<(input.size-2)},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tinputView.refresh;\r\n\t\t\t\t\t\tinputVertAxis.refresh;\r\n\t\t\t\t\t\ttransferView.refresh;\r\n\t\t\t\t\t\ttransferHorizAxis.refresh;\r\n\t\t\t\t\t\toutputView.refresh;\r\n\t\t\t\t\t\tinc = inc + 1;\r\n\t\t\t\t\t\t0.02.wait;}\r\n\t\t\t\t)\r\n\t\t\t}.fork(AppClock);\r\n\t\t}.fork(AppClock);\r\n\t});\r\n}.fork(AppClock);\r\n)",
   "id" : "1-5bJ",
   "is_private" : null
}
