How to construct variable names from incoming data / tracking touches

I have the following problem:

I have incoming OSC data (3 integeres) from a multi-touch interface running a Processing sketch in a form of:

  • mount
  • touchID
  • Xcoord
  • Ycoord

i.e.: /p5ui 1234 0.5234895 0.1239498675

Each new touch creates a unique (increased by 1) touchID.

I would like that each touch creates a Synth and when that touch (finger) is off the surface it frees/fades that synth. of course X and Y would control some parameters of a synth. I was wondering if I can start a synth with some kind of Node ID variable created from touchID and then access it to control parameters and free it, but I’m clueless how to construct such an object/variable in order to instatiate a synth at the touch of a finger.

I can already get a “free” message (a ‘lost’ touch associated with the touchID).

Anyone has any ideas?

Check Ndef and Tdef.
Another way is to store each synth instance you create in a List or Array so you can access it later to free it.
But I’d rather use an envelope if you want decay and set the gate with the touch event.

Thanks for the pointer to Ndef. Looks like exactly what I needed. I used touchID.asSymbol in order to use a numerical value incoming via OSC as a name of a variable/synth.

Below is the code that I used to solve this problem, however I’m interested in the difference between .end and .free method to the Ndef instance. I’m not sure why the former actually clears all UGens but the latter does not. Also another problem is that after a while SC seem to run out of audio busses. How can I force Ndef to release audio busses so that new Ndefs can reuse them?


(
o = OSCFunc({
	arg msg, time, addr, recvPort;

	var touchID, touchX, touchY;
	touchID = msg[1];
	touchX = msg[2];
	touchY = msg[3];

	if ( touchX == -1, // when X is -1 it means finger was lifted
		{
			Ndef(touchID.asSymbol).end(1);
                        // Ndef(touchID.asSymbol).free(1); // does not frees all UGens!!!
		},
		{
			if (Ndef(touchID.asSymbol).isPlaying == false,
				
				{ // if is not playing
					Ndef(touchID.asSymbol).play;
					Ndef(touchID.asSymbol, {
						|freq,amp|
						SinOsc.ar([freq,freq * 1.001]) * (amp * 0.1)
					});
				},
				
				{ // else feel free to control the parameters!
					Ndef(touchID.asSymbol).set(\freq, touchX * 1000);
					Ndef(touchID.asSymbol).set(\amp, touchY);
				}
			)
		}
	);
}, '/p5ui'); // listening FROM all ports and addresses but on this path.
)


o.free;    // remove the OSCFunc when you are done.
Ndef.clear;
OSCFunc.clear;
s.freeAll;

General rule of thumb for programming: If you ever find yourself asking “how to construct variable names dynamically,” in almost every case, what you really want some kind of collection (data structure) – and not variables.

I’d recommend an IdentityDictionary for this case.

(Note that Ndef uses an IdentityDictionary internally for storage – so the proposed solution is using an IdentityDictionary.)

hjh

1 Like

Not sure what you’re trying to achieve, but if you want to use touch as a keypress/release, I’d use an envelope in the synthdef and trigger that with doneAction:2 if you want to free the synth on release.