Number Box Decimals Bug?

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,
	);
});
)
	aVal.string_(val.round(0.001));

Is there a reason why you’re using string_ instead of value_?

The issue is not reproducible if you set the value instead.

hjh

I was lazy and had started with StaticText, then just changed it to NumberBox, so I overlooked string_

Thanks!