How to get the value of a bus map to an Ndef parameter from the language?

I’d like to know how to get the value of a bus map to an Ndef parameter from the language ?
let’s say:

(
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(\testMap).play;

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

Ndef(\testMap).get(\freq1); // here I get the rate and Index of the bus eg: c43 how can I get the value of that control bus index 43 ?

I’d like to know the value of the bus from the language ? Is it possible ?

Here is what i came up with.
After mapping the Bus Ndef(...).get returns the Control-Bus-Object and you can send it the message get to get it-s value. But in the end that-s maybe just a clumsy way to write b.get

(
Ndef(\1, { arg a, b, c; Silent.ar });

s.waitForBoot {
	b = Bus.control(s, 1);
};
)

(
w = Ndef(\1).gui;
Ndef(\1).set(\a, b);
)

(
b.set(0.5);
Ndef(\1).get(\a).get; // -> Bus control index: 0 value: 0.5.
)

(
b.set(0.75);
Ndef(\1).get(\a).get; // -> Bus control index: 0 value: 0.75.
)

(
Ndef.clear;
w.close;
b.free
)

here is another version using BusPlug.

(
var trig = 1;
Environment.new.linkDoc;

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);
	sig = SinOsc.ar([freq1, 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(\testMap).play;
)

(
~busPlug1 = BusPlug.for(~ctlBus1);
~busPlug2 = BusPlug.for(~ctlBus2);

Ndef(\testMap).set(\freq1, ~busPlug1, \freq2, ~busPlug2, \amp, 0.08);
)

(
Ndef(\testMap).get(\freq1).asBus.get; // -> Bus control index: 0 value: 880.0.
Ndef(\testMap).get(\freq2).asBus.get; // -> Bus control index: 1 value: 1280.0.
)

(
Ndef.clear;
~ctlBus1.free;
~ctlBus2.free
)

Thank you for your answer.

I try your code, it works but in my case I need to do Ndef(\1).get(\a).getSynchronous; to actualy get the value.
In my use case I use Ndef(\1).map(\a, b.asMap); to map the bus to parameters, unfortunately in this case I got an error when I try to do Ndef(\1).get(\a).get; cause Ndef(\1).get(\a) return a symbol

ERROR: Message 'get' not understood.
Perhaps you misspelled 'next', or meant to call 'get' on another receiver?
RECEIVER:
   Symbol 'c140'
ARGS:
CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	Nil:handleError
		arg this = nil
		arg error = <instance of DoesNotUnderstandError>
	Thread:handleError
		arg this = <instance of Thread>
		arg error = <instance of DoesNotUnderstandError>
	Object:throw
		arg this = <instance of DoesNotUnderstandError>
	Object:doesNotUnderstand
		arg this = 'c140'
		arg selector = 'get'
		arg args = [*0]
	Interpreter:interpretPrintCmdLine
		arg this = <instance of Interpreter>
		var res = nil
		var func = <instance of Function>
		var code = "(
b.set(0.5);
Ndef(\1).get(\..."
		var doc = nil
		var ideClass = <instance of Meta_ScIDE>
	Process:interpretPrintCmdLine
		arg this = <instance of Main>
^^ ERROR: Message 'get' not understood.
Perhaps you misspelled 'next', or meant to call 'get' on another receiver?
RECEIVER: c140

But that’s ok, I’ll rewrite my code and I’ll replace Ndef(\1).map(\a, b.asMap); by Ndef(\1).set(\a, b);

Thank you for this one too.

Is there any advantages to prefer this way to the other with .getSynchronous ?

Cause in my case, it makes me rewrite more code and I’m lazy.

Are there any other benefits to use Ndef(\1).set(\a, b); (where b is a Bus) over Ndef(\1).map(\a, b.asMap); ?

Only if you are in a situation (for whatever reason) where you have no other means to send messages to the bus. Otherwise i would say it-s preferable to use asMap and send messages to the bus directly.

(
var trig = 1;
Environment.new.linkDoc;

s.waitForBoot {
	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);
	sig = SinOsc.ar([freq1, 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(\testMap).play;
}
)

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

~ctlBus1.getSynchronous; // -> 880
~ctlBus2.getSynchronous; // -> 1280.0

(
Ndef.clear;
~ctlBus1.free;
~ctlBus2.free
)

Note that NodeProxy and Ndef are optimized for control values, so you can also write something like:

Ndef(\freq, 560);
Ndef(\x, { SinOsc.ar(Ndef.kr(\freq)) * 0.1 });
fork { inf.do { |i| 0.1.wait; Ndef(\freq, 560 + (i.rand % 200)) } };

or if you want to map:

Ndef(\freq, 560);
Ndef(\x, { |freq=440| SinOsc.ar(freq) * 0.1 });
fork { inf.do { |i| 0.1.wait; Ndef(\freq, 560 + (i.rand % 200)) } };
Ndef(\x).set(\freq, Ndef(\freq));
1 Like

Thank you, I was aware of this but it doesn’t feet my needs.
Thank you for your help anyway (and thank you for SuperDirt)

1 Like