I’ve built an ADSR envelope GUI for myself to use as a template for other projects and I’m having trouble with NumberBox behavior.
I want 3 decimal places max for time and 2 max for level:
aVal=NumberBox(envGUI, 30@15).string_(atk).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
dVal=NumberBox(envGUI, 30@15).string_(dec).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
sVal=NumberBox(envGUI, 30@15).string_(sus ).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(2);
rVal=NumberBox(envGUI, 30@15).string_(rel).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
but as I move the sliders, I get a bunch of delinquent values (I listed only some of the ones in the sustain slider because the time values scale exponentially):
0.35000000000000003
0.41000000000000003
0.47000000000000003
0.5700000000000001
0.6900000000000001
Is this a bug of some sort? I’m guessing I can use .round(0.001) as a workaround, but I want to know why this is happening.
Incidentally, if anyone notices anything I could/should be doing differently here as best practice, please let me know! I tried using iteration to make some things a bit more dynamic but it didn’t work.
Prefatory note, I just changed StaticText to NumberBox and I haven’t yet added NumberBox.action function. I wanted to get the decimal issue figured out first.
Full code:
(
var win;
var envGUI, envWidget;
var aSlider, dSlider, sSlider, rSlider, curveSlider;
var aVal, dVal, sVal, rVal;
var atk, dec, sus, rel, curve;
var aSlidVal, dSlidVal, sSlidVal, rSlidVal;
/////test vars/////
var noiseSynth;
var buttonGUI, noiseButton;
///////////////////
Window.closeAll;
s.waitForBoot({
s.freeAll;
s.sync;
///SynthDef Test
SynthDef.new(\envNoise, {
arg amp=1, atk=0.01, dec=0.3, sus=0.5, rel=1.0, curve=(-4.0), gate=0, out=0;
var sig, env;
sig = WhiteNoise.ar;
env = EnvGen.ar(Env.adsr(atk, dec, sus, rel, curve:curve), gate);
sig = Pan2.ar(sig*env*amp, 0);
Out.ar(out, sig);
}).add;
noiseSynth = Synth(\envNoise);
});
win = Window("Env GUI", Rect(300,300,800,800)).front
.onClose_({s.freeAll});
envGUI = View(win, Rect(20,20,200,300));
envGUI.background_(Color.white)
.decorator_(FlowLayout(envGUI.bounds));
envWidget=EnvelopeView(envGUI,Rect(4,4,192,100));
envWidget.setEnv(Env.adsr(curve:0))
.keepHorizontalOrder_(true)
.editable_(false)
.drawRects_(false);
curveSlider=Slider(envGUI, 192@15).valueAction_(0.5)
.action_({
var val;
val = curveSlider.value.linlin(0.0,1.0,-4.0,4.0);
envWidget.curves_(val)
});
envGUI.decorator_(FlowLayout(envGUI.bounds, 15@128, 30@20));
atk=0.01;
dec=0.3;
sus=0.5;
rel=1.0;
curve=(0.0);
aSlidVal=atk.linlin(0.001,10.0,0.0,1.0);
dSlidVal=dec.linlin(0.001,10.0,0.0,1.0);
rSlidVal=rel.linlin(0.001,10.0,0.0,1.0);
aSlider = Slider(envGUI, 20@130)
.value_(aSlidVal)
.action_({
var val, rev;
rev =
val = aSlider.value.linexp(0.0,1.0,0.001,10.0);
envWidget
.selectIndex(1)
.x = val;
aVal.string_(val.round(0.001));
noiseSynth.set(\atk, val);
});
dSlider = Slider(envGUI, 20@130)
.value_(dSlidVal)
.action_({
var val;
val = dSlider.value.linexp(0.0,1.0,0.001,10.0);
envWidget
.selectIndex(2)
.x = val;
dVal.string_(val.round(0.001));
noiseSynth.set(\dec, val);
});
sSlider = Slider(envGUI, 20@130)
.value_(sus)
.action_({
envWidget
.selectIndex(2)
.y = sSlider.value;
sVal.string_(sSlider.value.round(0.01));
noiseSynth.set(\sus, sSlider.value);
});
rSlider = Slider(envGUI, 20@130)
.value_(rSlidVal.explin(0.001,10.0,0.0,1.0))
.action_({
var val;
val = rSlider.value.linexp(0.0,1.0,0.001,10.0);
envWidget
.selectIndex(3)
.x = val;
rVal.string_(val.round(0.001));
noiseSynth.set(\rel, val);
});
envGUI.decorator_(FlowLayout(envGUI.bounds, 10@262, 20@20));
aVal=NumberBox(envGUI, 30@15).string_(atk).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
dVal=NumberBox(envGUI, 30@15).string_(dec).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
sVal=NumberBox(envGUI, 30@15).string_(sus ).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(2);
rVal=NumberBox(envGUI, 30@15).string_(rel).font_(Font(\Courier, size:8)).align_(\center).maxDecimals_(3);
envGUI.decorator_(FlowLayout(envGUI.bounds, 12@280, 30@20));
StaticText(envGUI, 21@10).string_("Atk").font_(Font(size:11, bold:true)).align_(\center);
StaticText(envGUI, 21@10).string_("Dec").font_(Font(size:11, bold:true)).align_(\center);
StaticText(envGUI, 21@10).string_("Sus").font_(Font(size:11, bold:true)).align_(\center);
StaticText(envGUI, 21@10).string_("Rel").font_(Font(size:11, bold:true)).align_(\center);
rel.postln;
///Add Gate Button
buttonGUI = View(win, Rect(240, 20, 50, 50))
.background_(Color.white);
noiseButton = Button(buttonGUI, Rect(2,2,46,46))
.states_([["Gate", Color.black, Color.green], ["Gate", Color.black, Color.red]])
.valueAction_(0)
.action_({noiseSynth.set(\gate, noiseButton.value)})
.mouseDownAction_({
noiseSynth.set(
\gate, noiseButton.value,
);
});
)