Map / unmap Ndef and Synth

Hello everybody,

in the code below, I’d like to unmap busses from Ndef’s parameters.
It works if I don’t use .gui.checkUpdate before calling unmap but I have an error otherwise.
Unfortunately, in my context, I need to call .gui.checkUpdate before calling unmap how can I do that ?

(
var trig = 1;
SynthDef(\testMap, { arg amp = 0.1, gate = 1, freq1 = 440, freq2 = 420;
	var sig, env;
	sig = SinOsc.ar([freq1.poll(trig, label: \SynthDef_freq1), freq2.poll(trig, label: \SynthDef_freq2)], 0.0);
	env = Env.asr.kr(doneAction: 2, gate: gate);
	sig = sig * env * amp;
	OffsetOut.ar(0, sig);
}).add;

Ndef(\testMap, { arg amp = 0.1, fadeTime = 0.02, gate = 1, freq1 = 440, freq2 = 420;
	var sig, env;
	sig = SinOsc.ar([freq1.poll(trig, label: \Ndef_freq1), freq2.poll(trig, label: \Ndef_freq2)], 0.0);
	env = Env.asr(fadeTime, 1.0, fadeTime).kr(doneAction: 2, gate: gate);
	sig = sig * env * amp;
	sig;
});

~ctlBus1 = Bus.control(s, 1);
~ctlBus2 = Bus.control(s, 1);
)

~ctlBus1.set(880);
~ctlBus2.set(1280);

// Ndef

Ndef(\testMap).play;

Ndef(\testMap).map(\freq1, ~ctlBus1.asMap, \freq2, ~ctlBus2.asMap, \amp, 0.08);

Ndef(\testMap).gui.checkUpdate;

Ndef(\testMap).unmap(*[\freq1, \freq2]); // ERROR: Message 'constrain' not understood. if executed after Ndef(\testMap).gui.checkUpdate;

Ndef(\testMap).unmap(\freq1, \freq2); // ERROR: Message 'constrain' not understood. if executed after Ndef(\testMap).gui.checkUpdate;

Ndef(\testMap).clear;

// SynthDef

~synth = Synth(\testMap, [\freq1, 220, \freq2, 240, \amp, 0.2]);

~synth.map(\freq1, ~ctlBus1, \freq2, ~ctlBus2);

~synth.unmap(\freq1, \freq2); // How do you unmap Synth ?

~synth.free;

I also wonder how can I do the same (unmap busses) in a Synth instance ?
synth.unmap(\freq1, \freq2); doesn’t work, what is the equivalent for Synth ?

Thank you and merry christmas

To unmap, simply .set the control to a new value.

hjh

Thank you and for the error, is this a bug ?

I’m not a very deep user of JITLib (just occasional), so I don’t know.

hjh

It is an incompatibility in the GUI with the use of control bus symbols that come from asMap.

The error message is quite clear in this case:

ERROR: Message 'constrain' not understood.
RECEIVER:
   nil
ARGS:
   Integer 400
KEYWORD ARGUMENTS:

PROTECTED CALL STACK:
	Meta_MethodError:new	0x7f83e04ac440
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x7f83e04aef80
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = constrain
		arg args = [400]
		arg keywordArgumentPairs = []
	Object:doesNotUnderstand	0x7f8400144540
		arg this = nil
		arg selector = constrain
		arg args = nil
		arg kwargs = nil
	EZSlider:value_	0x7f83e850f000
		arg this = an EZSlider
		arg val = 400
	ParamView:value_	0x7f84103cd680
		arg this = a ParamView
		arg val = 400

So the ParamView tries to set the EZSlider to a value and the ControlSpec that was automatically generated by the GUI somehow tries to calculate with the string from the bus.

We’ll have to dig into this a little.

But for now, you should be fine if you set the controls first before making the gui and mapping them.

// this works fine:
Ndef.clear;
~ctlBus1 = Bus.control(s, 1);
~ctlBus1.set(880);
Ndef(\testMap, { |freq1=440| freq1.poll(1); 0 }); 
Ndef(\testMap).set(\freq1, 500);
Ndef(\testMap).gui.checkUpdate;
Ndef(\testMap).map(\freq1, ~ctlBus1.asMap);
Ndef(\testMap).unmap(\freq1);

// this fails (map before set):
Ndef.clear;
~ctlBus1 = Bus.control(s, 1);
~ctlBus1.set(880);
Ndef(\testMap, { |freq1=440| freq1.poll(1); 0 }); 
Ndef(\testMap).map(\freq1, ~ctlBus1.asMap);
Ndef(\testMap).gui.checkUpdate;
Ndef(\testMap).unmap(\freq1);

OK, some digging:

Ndef.clear;
~ctlBus1 = Bus.control(s, 1);
~ctlBus1.set(880);
Ndef(\testMap, { |freq1=440|  0 }); 
Ndef(\testMap).map(\freq1, ~ctlBus1.asMap);
~gui = Ndef(\testMap).gui;
~gui.checkUpdate;
~gui.paramGui.specs; //
~gui.paramGui.getSpec // empty ... 
~gui.paramGui.paramViews[0].label // freq1
~gui.paramGui.paramViews[0].slider
~gui.paramGui.paramViews[0].slider.controlSpec // nil
~gui.paramGui.paramViews[0].slider.controlSpec = \freq.asSpec;
Ndef(\testMap).unmap(\freq1); // now it works ...

So the slider requires a control spec, but has none, because a string.

This might come from:

Spec.guess(\freq1, "c0") // -> nil

but I am not sure, maybe @adcxyz or @adc has an idea?

The quick answer is:
JITGuis only do Spec.guess for parameter as an attempt
to show something useful initially, before users set a spec
that works well for them; these specs are meant to be tuned
just in time while you try what feels good.
So, the best fix to never see this problen is to set an OK spec
initially, and as you play with the Ndef, tune it to what you like.

So if you do, e.g. this first:

Ndef(\testMap).addSpec(\freq1, \freq);
Ndef(\testMap).addSpec(\freq2, \freq);

the error never happens.

Explanations inline:

// this works fine:
Ndef.clear;
~ctlBus1 = Bus.control(s, 1);
~ctlBus1.set(880);
Ndef(\testMap, { |freq1=440| freq1.poll(1); 0 }); 
Ndef(\testMap).set(\freq1, 500);
// gui finds number value, for freq1 and guesses
Spec.guess(freq1, 500);  // -> ControlSpec(25, 10000, \exp);
// so the gui works ok with the guessed spec.
Ndef(\testMap).gui.checkUpdate;
Ndef(\testMap).map(\freq1, ~ctlBus1.asMap);
Ndef(\testMap).unmap(\freq1);

// this fails (map before set):
Ndef.clear;
~ctlBus1 = Bus.control(s, 1);
~ctlBus1.set(880);
Ndef(\testMap, { |freq1=440| freq1.poll(1); 0 }); 
Ndef(\testMap).map(\freq1, ~ctlBus1.asMap);
// gui finds freq1 has value \c4, which it has no way to guess a a reasonable range for
Spec.guess(freq1, \c4);  // -> nil
Ndef(\testMap).gui.checkUpdate;
// so when you switch back to a number value, 
// it does not have a spec ready to go, 
// and does not try again to guess one now.
Ndef(\testMap).unmap(\freq1);

Hope this helps?
Best adc

thanks for looking into this @julian, @adc. when does it make sense to use checkUpdate manually? i thought that was a message only used by SkipJack.
https://docs.supercollider.online/Classes/JITGui.html#-checkUpdate

you can use .checkUpdate manually whenever you want that jitgui to check whether its displayed state still matches the state of its object, and update its display.
JITGuis use skipjacks to run this at an appropriate update rate (such as every 0.2 seconds).

Are you using the JITLibExtensions quark?
I’ve looked at the checkUpdate methods of EnvirGui and NdefParamGui,
and they both do not cover the same corner case you found,
where a param value goes from non-number to number,
and the paramgui does to try to guess a spec again for that param name.
Wondering whether it is worth to try to fix this rare corner case - never heard this one before.

the corner case was found by @kesey but i got interested and found another variant to trigger it.

// Works
Ndef.clear;
Ndef(\ctlBus1, 880);
Ndef(\testMap, { |freq1=440| SinOsc.ar(freq1) * 0.3 }).play;
n = Ndef(\testMap).gui;
Ndef(\testMap).set(\freq1, Ndef(\ctlBus1));
Ndef(\testMap).set(\freq1, 440);

n.close

// Error
Ndef.clear;
Ndef(\ctlBus1, 880);
Ndef(\testMap, { |freq1=440| SinOsc.ar(freq1) * 0.3 }).play;
Ndef(\testMap).set(\freq1, Ndef(\ctlBus1));
n = Ndef(\testMap).gui;
Ndef(\testMap).set(\freq1, 440);

-> Ndef
-> Ndef('ctlBus1')
-> Ndef('testMap')
-> Ndef('testMap')
-> a NdefGui
-> Ndef('testMap')
ERROR: Message 'constrain' not understood.
RECEIVER:
   nil
ARGS:
   Integer 440
KEYWORD ARGUMENTS:

PROTECTED CALL STACK:
	Meta_MethodError:new	0x1393b6840
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x1393b8f80
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = constrain
		arg args = [440]
		arg keywordArgumentPairs = []
	Object:doesNotUnderstand	0x13856b300
		arg this = nil
		arg selector = constrain
		arg args = nil
		arg kwargs = nil
	EZSlider:value_	0x13b1afe00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0x138955400
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0x13ab0a080
		arg this = [freq1]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0x1392d5180
		arg this = a NdefParamGui
		arg newKeys = [freq1]
		arg newSettings = [[freq1, 440]]
		var prevSettings = [[freq1, Ndef('ctlBus1')]]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0x1392d4a40
		arg this = a NdefParamGui
		var newState = ('editKeys': [freq1], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [[freq1, 440]], 'specsToUse': [a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess')])
		var newKeys = [freq1]
	a FunctionDef	0x13a0e2e40
		sourceCode = "<an open Function>"
	Routine:prStart	0x139fd4640
		arg this = a Routine
		arg inval = 40.298827583

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Function:try
		arg this = <instance of Function>
		arg handler = <instance of Function>
		var result = <instance of DoesNotUnderstandError>
	< FunctionDef in Method Scheduler:seconds_ >
		arg time = 55.26596125
		arg item = <instance of Routine>
	< FunctionDef in Method SequenceableCollection:pairsDo >
		arg i = 0
	Integer:forBy
		arg this = 0
		arg endval = 2
		arg stepval = 2
		arg function = <instance of Function>
		var i = 0
		var j = 0
	SequenceableCollection:pairsDo
		arg this = [*4]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 55.267387958
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'constrain' not understood.
RECEIVER: nil


ERROR: Message 'constrain' not understood.
RECEIVER:
   nil
ARGS:
   Integer 440
KEYWORD ARGUMENTS:

PROTECTED CALL STACK:
	Meta_MethodError:new	0x1393b6840
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x1393b8f80
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = constrain
		arg args = [440]
		arg keywordArgumentPairs = []
	Object:doesNotUnderstand	0x13856b300
		arg this = nil
		arg selector = constrain
		arg args = nil
		arg kwargs = nil
	EZSlider:value_	0x13b1afe00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0x138955400
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0x13ab0a080
		arg this = [freq1]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0x1392d5180
		arg this = a NdefParamGui
		arg newKeys = [freq1]
		arg newSettings = [[freq1, 440]]
		var prevSettings = [[freq1, Ndef('ctlBus1')]]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0x1392d4a40
		arg this = a NdefParamGui
		var newState = ('editKeys': [freq1], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [[freq1, 440]], 'specsToUse': [a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess')])
		var newKeys = [freq1]
	NdefGui:checkUpdate	0x13934a2c0
		arg this = a NdefGui
		var newState = ('object': Ndef('testMap'), 'name': testMap, 'isPlaying': true, 'isPaused': false, 
  'canSend': true, 'type': ar 1, 'fadeTime': 0.02)
	a FunctionDef	0x13a0e2e40
		sourceCode = "<an open Function>"
	Routine:prStart	0x139fd4640
		arg this = a Routine
		arg inval = 40.299114208

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Function:try
		arg this = <instance of Function>
		arg handler = <instance of Function>
		var result = <instance of DoesNotUnderstandError>
	< FunctionDef in Method Scheduler:seconds_ >
		arg time = 55.266604542
		arg item = <instance of Routine>
	< FunctionDef in Method SequenceableCollection:pairsDo >
		arg i = 2
	Integer:forBy
		arg this = 0
		arg endval = 2
		arg stepval = 2
		arg function = <instance of Function>
		var i = 2
		var j = 1
	SequenceableCollection:pairsDo
		arg this = [*4]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 55.267387958
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'constrain' not understood.
RECEIVER: nil

and second error on pressing cmd-.

ERROR: Message 'round' not understood.
RECEIVER:
   nil
ARGS:
   Float 0.001000   D2F1A9FC 3F50624D
KEYWORD ARGUMENTS:

PROTECTED CALL STACK:
	Meta_MethodError:new	0x1393b6840
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x1393b8f80
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = round
		arg args = [0.001]
		arg keywordArgumentPairs = []
	Object:doesNotUnderstand	0x13856b300
		arg this = nil
		arg selector = round
		arg args = nil
		arg kwargs = nil
	EZSlider:value_	0x13b1afe00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0x138955400
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0x13ab0a080
		arg this = [freq1]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0x1392d5180
		arg this = a NdefParamGui
		arg newKeys = [freq1]
		arg newSettings = [[freq1, 440]]
		var prevSettings = [[freq1, Ndef('ctlBus1')]]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0x1392d4a40
		arg this = a NdefParamGui
		var newState = ('editKeys': [freq1], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [[freq1, 440]], 'specsToUse': [a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess')])
		var newKeys = [freq1]
	a FunctionDef	0x13a0e2e40
		sourceCode = "<an open Function>"
	Routine:prStart	0x139fd4640
		arg this = a Routine
		arg inval = 40.298827583

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Function:try
		arg this = <instance of Function>
		arg handler = <instance of Function>
		var result = <instance of DoesNotUnderstandError>
	< FunctionDef in Method Scheduler:seconds_ >
		arg time = 142.042366
		arg item = <instance of Routine>
	< FunctionDef in Method SequenceableCollection:pairsDo >
		arg i = 2
	Integer:forBy
		arg this = 0
		arg endval = 8
		arg stepval = 2
		arg function = <instance of Function>
		var i = 2
		var j = 1
	SequenceableCollection:pairsDo
		arg this = [*10]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 142.043287292
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'round' not understood.
RECEIVER: nil


ERROR: Message 'round' not understood.
RECEIVER:
   nil
ARGS:
   Float 0.001000   D2F1A9FC 3F50624D
KEYWORD ARGUMENTS:

PROTECTED CALL STACK:
	Meta_MethodError:new	0x1393b6840
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x1393b8f80
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = round
		arg args = [0.001]
		arg keywordArgumentPairs = []
	Object:doesNotUnderstand	0x13856b300
		arg this = nil
		arg selector = round
		arg args = nil
		arg kwargs = nil
	EZSlider:value_	0x13b1afe00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0x138955400
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0x13ab0a080
		arg this = [freq1]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0x1392d5180
		arg this = a NdefParamGui
		arg newKeys = [freq1]
		arg newSettings = [[freq1, 440]]
		var prevSettings = [[freq1, Ndef('ctlBus1')]]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0x1392d4a40
		arg this = a NdefParamGui
		var newState = ('editKeys': [freq1], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [[freq1, 440]], 'specsToUse': [a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess')])
		var newKeys = [freq1]
	NdefGui:checkUpdate	0x13934a2c0
		arg this = a NdefGui
		var newState = ('object': Ndef('testMap'), 'name': testMap, 'isPlaying': true, 'isPaused': false, 
  'canSend': true, 'type': ar 1, 'fadeTime': 0.02)
	a FunctionDef	0x13a0e2e40
		sourceCode = "<an open Function>"
	Routine:prStart	0x139fd4640
		arg this = a Routine
		arg inval = 40.299114208

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Function:try
		arg this = <instance of Function>
		arg handler = <instance of Function>
		var result = <instance of DoesNotUnderstandError>
	< FunctionDef in Method Scheduler:seconds_ >
		arg time = 142.042403917
		arg item = <instance of Routine>
	< FunctionDef in Method SequenceableCollection:pairsDo >
		arg i = 4
	Integer:forBy
		arg this = 0
		arg endval = 8
		arg stepval = 2
		arg function = <instance of Function>
		var i = 4
		var j = 2
	SequenceableCollection:pairsDo
		arg this = [*10]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 142.043287292
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'round' not understood.
RECEIVER: nil


Safety('localhost') is running, using 'safeClip_2'.

OK, thanks!
I figured out the logic error/assumption in the checkUpdate methods:
update the specs first, then the param settings.

Please Try it, and see if you find more orner cases:

Quark("JITLibExtensions").update; 
this.recompile;
// this one is fine now:
Ndef.clear;
Ndef(\ctlBus1, 880);
Ndef(\testMap, { |freq1=440| SinOsc.ar(freq1) * 0.3 }).play;
Ndef(\testMap).set(\freq1, Ndef(\ctlBus1));
n = Ndef(\testMap).gui;
Ndef(\testMap).set(\freq1, 440);

Very cool!
worked after changing this.recompile to thisProcess.recompile
Thank you very much.

Hello,

thank you for taking the time to look at this.
After executing this:

Quark("JITLibExtensions").update;
thisProcess.recompile
// this one is fine now:
Ndef.clear;
Ndef(\ctlBus1, 880);
Ndef(\testMap, { |freq1=440| SinOsc.ar(freq1) * 0.3 }).play;
Ndef(\testMap).set(\freq1, Ndef(\ctlBus1));
n = Ndef(\testMap).gui;
Ndef(\testMap).set(\freq1, 440);

I still have errors on a windows 10 machine with SuperCollider 3.13

ERROR: Message 'constrain' not understood.
RECEIVER:
   nil
ARGS:
   Integer 440

PROTECTED CALL STACK:
	Meta_MethodError:new	0000024BADD37240
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0000024BADD39580
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = constrain
		arg args = [ 440 ]
	Object:doesNotUnderstand	0000024BB0DEA000
		arg this = nil
		arg selector = constrain
		arg args = nil
	EZSlider:value_	0000024BB0B87F00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0000024BAFE1B900
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0000024BB0403480
		arg this = [ freq1 ]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0000024BADC08E00
		arg this = a NdefParamGui
		arg newKeys = [ freq1 ]
		arg newSettings = [ [ freq1, 440 ] ]
		var prevSettings = [ [ freq1, Ndef('ctlBus1') ] ]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0000024BADC086C0
		arg this = a NdefParamGui
		var newState = ( 'editKeys': [ freq1 ], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [ [ freq1, 440 ] ], 'specsToUse': [ a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess') ] )
		var newKeys = [ freq1 ]
	a FunctionDef	0000024BB00BEC40
		sourceCode = "<an open Function>"
	Routine:prStart	0000024BB0043580
		arg this = a Routine
		arg inval = 901.6116528

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Integer:forBy
		arg this = 0
		arg endval = 2
		arg stepval = 2
		arg function = <instance of Function>
		var i = 0
		var j = 0
	SequenceableCollection:pairsDo
		arg this = [*4]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 908.1336795
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'constrain' not understood.
RECEIVER: nil


ERROR: Message 'constrain' not understood.
RECEIVER:
   nil
ARGS:
   Integer 440

PROTECTED CALL STACK:
	Meta_MethodError:new	0000024BADD37240
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0000024BADD39580
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = constrain
		arg args = [ 440 ]
	Object:doesNotUnderstand	0000024BB0DEA000
		arg this = nil
		arg selector = constrain
		arg args = nil
	EZSlider:value_	0000024BB0B87F00
		arg this = an EZSlider
		arg val = 440
	ParamView:value_	0000024BAFE1B900
		arg this = a ParamView
		arg val = 440
	ArrayedCollection:do	0000024BB0403480
		arg this = [ freq1 ]
		arg function = a Function
		var i = 0
	NdefParamGui:setByKeys	0000024BADC08E00
		arg this = a NdefParamGui
		arg newKeys = [ freq1 ]
		arg newSettings = [ [ freq1, 440 ] ]
		var prevSettings = [ [ freq1, Ndef('ctlBus1') ] ]
		var newVal = 440
		var oldVal = Ndef('ctlBus1')
		var oldKey = freq1
	NdefParamGui:checkUpdate	0000024BADC086C0
		arg this = a NdefParamGui
		var newState = ( 'editKeys': [ freq1 ], 'keysRotation': 0, 'object': Ndef('testMap'), 'overflow': 0, 
  'settings': [ [ freq1, 440 ] ], 'specsToUse': [ a ControlSpec(22.0, 8800, 'exp', 0, 440, 'guess') ] )
		var newKeys = [ freq1 ]
	NdefGui:checkUpdate	0000024BADCB6440
		arg this = a NdefGui
		var newState = ( 'object': Ndef('testMap'), 'name': testMap, 'isPlaying': true, 'isPaused': false, 
  'canSend': true, 'type': ar 1, 'fadeTime': 0.02 )
	a FunctionDef	0000024BB00BEC40
		sourceCode = "<an open Function>"
	Routine:prStart	0000024BB0043580
		arg this = a Routine
		arg inval = 901.6119571

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Integer:forBy
		arg this = 0
		arg endval = 2
		arg stepval = 2
		arg function = <instance of Function>
		var i = 2
		var j = 1
	SequenceableCollection:pairsDo
		arg this = [*4]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 908.1336795
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ ERROR: Message 'constrain' not understood.
RECEIVER: nil

I can see this when I update the Quarks (I assumed it’s ok):

Quark 'JITLibExtensions' updated to version: 0.1 tag: nil refspec: 669ecd41d8021e9f3c6e2c972224b0f2c281009e
-> Quark: JITLibExtensions[0.1]