Mapping Pdefn to Controllers

I like being able to map x.set variables to be controlled by touch OSC, or by GUIs. I figured out how to change parameters of of Pbinds by using Pdefn. But because those messages are not x.set messages, I haven’t figured out a solution to have them controlled by something, other than typing it in. Is there a way around this that I’ve overlooked? Here is an example using touch osc.

//8 chan version
(
SynthDef(\plucking, {
arg amp = 0.1, freq = 440, decay = 5, coef = 0.1, pan=1, out=0;
var env, sig;
env = EnvGen.kr(Env.linen(0, decay, 0), doneAction: 2);
sig = Pluck.ar(
in: WhiteNoise.ar(amp),
trig: Impulse.kr(0),

    maxdelaytime: 0.1,
    delaytime: freq.reciprocal,
    decaytime: decay,
    coef: coef
);
sig = PanAz.ar(8, sig, pan);
Out.ar(out, sig);

}).add;
)

(
Pdefn(\pan, 0.1); //allows you to use pan as a nice argument
Pdefn(\degree, Pwhite(7, 15));

b = Pbind(
\instrument, “plucking”,
\scale, Scale.lydian,
//\pan, Pwhite(0.1, 1.7, inf), //randomized 8 chan spatialization on its own
\pan, Pdefn(\pan), //allows you to control the pan manually!!!
\degree, Pdefn(\degree), //7-15 is the normal range. But can expand larger. -20-0 sounds more angry harpsichord-like. 20-30 is really high.
\amp, Pwhite(0.1, 0.5),
\decay, Pwhite(7, 12), //7, 12
\coef, Pwhite(0.01, 0.1),
\dur, Prand([0.1, 0.2, 0.4, 0.27, 0.13, 0.38], inf)
).play;
)

Pdefn(\pan, 0.1); //0.1 - 1.6; 1.7 = chans 0 and 7
Pdefn(\degree, Pwhite(7, 30)); //Since there are two variables, I can’t figure out a way to map a controller onto this…

b.pause; // will resume where paused.
b.play;
b.reset
b.stop;

(
OSCdef.new(
\push1,
{
arg msg;
b.play(msg[2]); //will get a message saying "already playing, but it works!
},
‘/1/push1’,
recvPort:8000
);
OSCdef.new(
\push2,
{
arg msg;
b.pause(msg[2]);
},
‘/1/push2’,
recvPort:8000
);
)

I’m somewhat confused as to what you are trying to do.
Are you trying to change the “7” and the “30” dynamically from a received OSC message in the following line?

Pdefn(\degree, Pwhite(7, 30)); //-20 - 30. Since there are two variables, I can’t figure out a way to map a controller onto this…

If so, you can use environment variables, e.g.

// first run this
(
s.waitForBoot({
    ~lower = 0;
    ~upper = 12;
    ~pat = Pbind(\instrument, \default,
        \degree, Pwhite(Pfunc{~lower},Pfunc{~upper})
    );
    ~player = ~pat.play;
});
)

// then a bit later, change the boundaries -> this is what you should in your osc handler
(
~lower=13; 
~upper=24;
)

7-30 is the range. So on an OSC fader, or a GUI fader. I want to be able to change the the minimum and maximum values for the degree.

However, even if it was a parameter with a single number, I don’t know how to get anything to map onto it because the message for the Pbind needs to be: Pdefn(\name, number);
But every example I’ve come across with mapping, the controller or GUI needs the message to be: x.set(\name, number);
or else it doesn’t work for the controller.

Did you try something like the example code I added on the forum?
(If you are reading this by email, it might be that you didn’t see my edit - not sure how this aspect of the forum works.)

I don’t know how a ~name = number would be written inside an OSC mapping. This is the syntax that I learned how to write it as:

    (
OSCdef.new(
	\push1,
	{
		arg msg;
		b.play(msg[2]); //will get a message saying "already playing, but it works!
	},
	'/1/push1',
	recvPort:8000
);
OSCdef.new(
	\push2,
	{
		arg msg;
		b.pause(msg[2]);
	},
	'/1/push2',
	recvPort:8000
);
OSCdef.new(
	\fader1,
	{
		arg msg;
		c.set(\rate, msg[1].linexp(0,1,0.3,5));//how you map the fader values to the values needed in SC.
	},
	'/1/fader1',
	recvPort:8000
);
OSCdef.new(
	\fader4,
	{
		arg msg;
		c.set(\mix, msg[1].linexp(0,1,0.1,1));
	},
	'/1/fader4',
	recvPort:8000
);
OSCdef.new(
	\fader5,
	{
		arg msg;
		c.set(\amp, msg[1].linexp(0,1,0.01,12));
	},
	'/1/fader5',
	recvPort:8000
);
OSCdef.new(
	\rotary1,
	{
		arg msg;
		c.set(\pan, msg[1].linlin(0,1,0.1,1.7));//linlin works with pan, but linexp does not.
	},
	'/1/rotary1',
	recvPort:8000
);
)

In a first approximation. you can think of ~name (i.e. a variable name preceded by a tilde) as a kind of “global” variable. Such variable is accessible both inside the OSCdef handler and outside it. This means that where you now write c.set(\key, value), you can instead write ~name = value.

(Actually, single character variables (like your ‘b’ and ‘c’) are implicitly interpreted as being the same kind of “global” variable, so you were already using the mechanism without fully realizing it.The correct name for a ~variablename (with a tilde) is “environment variable”, and you can e.g. read something about those variables here: 10_Controls | SuperCollider 3.12.2 Help as well as by googling for “supercollider environment variable” )