// title: Attack Detection and Amplitude Threshold Setter GUI // author: eli.fieldsteel // description: // A modular GUI designed to detect amplitude attacks and set a globally retrievable threshold value. // code: // VIDEO: http://www.youtube.com/watch?v=pFLj7yJzp60 ( s = Server.local; ~threshTest = nil; s.waitForBoot({ SynthDef(\threshTest, { arg thresh=(-30); var sig, amp, trig; sig = SoundIn.ar(0); amp = Amplitude.kr(sig).ampdb; amp = K2A.ar(amp); trig = amp >= thresh; SendReply.ar(Impulse.ar(50), 'trigVal', [trig]); }).add; w = Window.new("amplitude threshold tester", Rect(600, 250, 950, 220)).front; w.view.background_(Color.gray(0.75)); w.onClose_({s.freeAll}); ~numberBox = NumberBox.new(w, Rect(180, 25, 450, 120)) .font_(Font("Helvetica", 108)) .value_(-30) .action_({ |nb| nb.value.postln; ~knob.value_((nb.value.dbamp) / (~maxValSlider.value.dbamp)); if(~threshTest.notNil, { if(~threshTest.group.class == Group, {~threshTest.set(\thresh, nb.value)}, {} ); }, {} ); }); ~knob = Knob.new(w, Rect(20, 20, 150, 150)) .background_(Color.gray(0.75)) .color_([Color.blue(0.9,0.5), Color.green(0.65), Color.gray(0.6), Color.black]) .value_(~numberBox.value.dbamp) .action_({ |knob| ~numberBox.valueAction_((knob.value * ~maxValSlider.value.dbamp).ampdb); }); ~maxValSlider = EZSlider( w, Rect(20, 160, 612, 40), "knob max", ControlSpec.new(-90,0,\lin,0.1,0,""), { |slider| ~numberBox.valueAction_((~knob.value * slider.value.dbamp).ampdb) }, 1, false, 120, 65, 0, 20, \horz, 2@2, 2@2 ) .setColors(knobColor:Color.blue(0.9,0.5)) .font_(Font("Helvetica", 24)); ~testButton = Button.new(w, Rect(650, 25, 160, 40)) .states_([ ["start test", Color.white, Color.green(0.65)], ["stop test", Color.white, Color.red(0.65)] ]) .action_({ |but| case {but.value == 0} {~threshTest.free} {but.value == 1} {~threshTest = Synth(\threshTest, [\thresh, ~numberBox.value])}; }) .font_(Font("Helvetica", 32)); ~received = TextView(w, Rect(750, 95, 170, 60)) .visible_(false) .editable_(false) .string_("received") .font_(Font("Helvetica", 42)) .stringColor_(Color.black) .background_(Color.gray(0.725)); w.drawHook = { |v| Pen.fillColor = Color.gray(0.75); Pen.strokeColor = Color.black; Pen.width = 3; Pen.addArc(700@125, 35, 0, 2pi); Pen.fillStroke; }; w.refresh; ~oscr1.remove; ~oscr1 = OSCresponder(nil, 'trigVal', { |time, resp, msg| if( msg[3] == 1, { Routine { w.drawHook = { |v| Pen.fillColor = Color.green; Pen.strokeColor = Color.black; Pen.width = 3; Pen.addArc(700@125, 35, 0, 2pi); Pen.fillStroke; }; w.refresh; ~received.visible_(true); 0.1.wait; w.drawHook = { |v| Pen.fillColor = Color.gray(0.75); Pen.strokeColor = Color.black; Pen.width = 3; Pen.addArc(700@125, 35, 0, 2pi); Pen.fillStroke; }; w.refresh; ~received.visible_(false); }.play(AppClock); }, {} ); }).add; }) )