Is a Node with NodeId still running?

Hello, I was playing with Ndefs and try to figure out how to know if a Synth is still running by knowing only its NodeID.

So if i know the NoteID only, how do i make a false or true statement, if the Synth/node is still running (lets say some time after the Synth is released).

I know the ID by this line.
Ndef(\test).objects[60].nodeID
maybe there is even a better way to figure out if the Ndef(\test) at position 60 is still running.

Anyhow. Thank you very much!

Lets say i want to know something about the synth with a nodeID 1031.
And if it is running, i want to change its \freq with this:

s.sendMsg("/n_set", 1031, \freq, 440);

However it is not always running, how do i figure out if it is still running?

To my knowledge, there is no server command for this.

If you know what group it’s in, you might be able to /g_queryTree and check the reply – but if you know the group, then you probably don’t need to query the specific node anyway.

The best way is really to proactively track the nodes, not retroactively ask.

hjh

1 Like

There’s also the NodeWatcher -

https://doc.sccode.org/Classes/NodeWatcher.html

/n_query might give you what you’re after, or use /notify and listen for the /n_ends

Hm, I’d missed that command.

The thing to check with a command like this is – do you get anything back if the node isn’t there?

Turns out you do…

s.boot;

OSCFunc.trace(true, true);

s.sendMsg(\n_query, 1000);  // 1000 doesn't exist

OSC Message Received:
	time: 17.836730349
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /fail, /n_query, Node 1000 not found ]

So you can register two OSCFuncs: /n_info (with argTemplate: [theNodeID]) and /fail (with argTemplate: ['/n_query']) – and be sure to clean them both up when either one is received.

hjh

thanks! how do i get a true or false sentence out though? currently i see only the message in the post window

It depends whether you’re okay with waiting for an answer from the server, or if you need the answer synchronously, Right Now.

// asynchronous way
(
~checkNodeID = { |id, timeout = 0.2|
	var okResp, failResp;
	var cond = CondVar.new;
	var answer;
	
	okResp = OSCFunc({ |msg|
		answer = true;
		cond.signalOne;
	}, '/n_info', s.addr, argTemplate: [id]);
	failResp = OSCFunc({ |msg|
		if(msg[2].asString.contains(id.asString)) {
			answer = false;
			cond.signalOne;
		};
	}, '/fail', s.addr, argTemplate: ['/n_query']);
	
	s.sendMsg(\n_query, id);
	cond.waitFor(timeout, { answer.notNil });
	
	okResp.free;
	failResp.free;
	
	answer
};
)

fork { ~checkNodeID.(1000).postln };

~checkNodeID can be called only within a Routine. There’s no way around that. If you’re going to ask the server, then you have to wait for the answer. The Routine waits for the answer.

Note also that the server will post “node not found” if the node isn’t there. I tried to turn that off, but then it doesn’t send the ‘fail’ message either – so you’re stuck with it. (This goes back to a general point… often a question like this is phrased in terms of “how do I ask the server xyz?” but quite often, this ends up being impractical.)

If that’s not acceptable, then the only other way is to mirror the ID on/off states in the client, all the time.

(
var activeNodes = IdentitySet.new;

OSCdef(\onResp, { |msg|
	activeNodes.add(msg[1]);
}, '/n_go', s.addr);  // here it's bound to a specific server though

OSCdef(\offResp, { |msg|
	activeNodes.remove(msg[1]);
}, '/n_end', s.addr);

~checkNodeID = { |id|
	activeNodes.includes(id)
};
)

This function, you can call in any context.

hjh